首页 > 编程语言 >python实现二叉树并且遍历

python实现二叉树并且遍历

时间:2022-10-25 16:58:14浏览次数:80  
标签:左子 遍历 python self 访问 二叉树 root 节点

python实现二叉树并且遍历

2.1 二叉树的遍历

2.1.1 前序遍历 (根左右)

二叉树的前序遍历的步骤如下:

访问树的根节点----> 访问当前节点的左子树---->若当前节点无左子树,访问当前节点的右子树。

img

以上图为例,对其进行前序遍历的步骤为:

  1. 先访问根节点,得到1

  2. 访问根节点1的左子节点2,发现左子节点2还有左子节点4,继续向下访问,直到最后一个左子节点8,发现8为叶子节点。继续访问其父节点4的右子节点9,发现右子节点9为叶子节点。得到序列2、4、8、9.

  3. 根据“根左右”的顺序,访问左子节点2的右子节点5,其有左子节点10,但是10为叶子节点,得到序列:5、10。至此二叉树的左子树遍历完毕,得到以下序列:1、2、4、8、9、5、10。

  4. 以类似的方式访问根节点1的右子节点3,访问左子节点6,其为叶子节点,继续访问其兄弟节点的右子节点7。至此,二叉树的右子树遍历完毕,得到以下序列:3、6、7。至此整棵二叉树的遍历完毕。

得到的结果为:1、2、4、8、9、5、10、3、6、7。

实现前序遍历通常有两种方式:递归实现遍历和利用堆栈实现遍历。

2.1.2 中序遍历(左根右)

二叉树的前序遍历的步骤如下:

访问当前节点的左子树----> 访问根节点---->访问当前节点的右子树。

img

同样的,以上图为例,对其进行中序遍历的步骤为:

  1. 按照“左根右”的顺序,先访问左子节点2,但是2还有左子节点4,4有左子节点8,而8为叶子结点,所以第1个访问的元素为8,接着访问节点8的父节点4,然后访问4的右子节点9.得到序列8、4、9。至此以4为根节点的左子树遍完毕。

  2. 访问节点4的父节点2,访问其右子节点5,但是节点5有左子节点10,10为叶子节点,得到的序列为:2、10、5。至此,以2为根节点的左子树的遍历完毕,得到序列:8、4、9、2、10、5。

  3. 访问整棵树的根节点1,访问其右子节点3,但其有左子节点6,6为叶子节点。所以最先访问的是6,接着访问其父节点3,再访问3的右子节点7,7为叶子节点,至此以1为根节点的右子树遍历完毕。得到序列1、6、3、7。至此整棵二叉树的遍历完毕。

得到的结果为:8、4、9、2、10、5、1、6、3、7

实现中序遍历同样有两种方式:递归实现遍历和利用堆栈实现遍历。

2.1.3 后序遍历(左右根)

二叉树的后序遍历步骤如下:

访问当前节点的左子树---->访问当前节点的右子树---->访问根节点

img

同样的,以上图为例,对其进行后序遍历的步骤:

  1. 按照“左右根”的顺序,首先访问节点8,接着访问节点9,因为节点8和节点9都为叶子节点,所以接下来访问节点4。至此以2为根节点的左子树遍历完毕,接着遍历以2为根节点的右子树,首先访问节点10,接着访问节点5,最后访问节点2。至此,以1为根节点的左子树的遍历完毕,得到的序列为:8、9、4、10、5。

  2. 遍历以1为根节点的右子树,首先访问节点6,接着访问节点7,因为节点6和节点7都是叶子节点,所以接下来访问节点3。最后访问整棵树的根节点1。至此,整棵树的遍历完毕。

得到的结果为:8、9、4、10、5、2、6、7、3、1

实现后序遍历同样有两种方式:递归实现遍历和利用堆栈实现遍历。

2.2 代码实现

class TreeNode():
    """定义树节点"""

    def __init__(self, data, left_child=None, right_child=None):
        """
        :param data: 树节点存储的数据
        :param left_child: 左子树
        :param right_child: 右子树
        """
        self.data = data
        self.left_child = left_child
        self.right_child = right_child


class BinaryTree():
    def __init__(self):
        self.root = None  # 初始化根节点为None
        self.ls = []  # 定义列表用于存储节点地址

    def add(self, data):
        """
        :param data: 要添加的数据
        :return:
        """
        node = TreeNode(data)  # 实例化树节点
        if self.root is None:  # 若根节点为None,添加根节点,并将根节点的地址添加到到self.ls中
            self.root = node
            self.ls.append(self.root)
        else:
            rootNode = self.ls[0]  # 将第一个元素设为根节点
            if rootNode.left_child is None:  # 若根节点的左孩子为None,添加左节点,并将左节点的地址添加到到self.ls中
                rootNode.left_child = node
                self.ls.append(rootNode.left_child)
            elif rootNode.right_child is None:  # 若根节点的右孩子为None,添加右节点,并将右节点的地址添加到到self.ls中
                rootNode.right_child = node
                self.ls.append(rootNode.right_child)
                self.ls.pop(0)  # 弹出self.ls中第一个元素

    def preOrderTraverse(self, root):
        """前序遍历"""
        if root is None:
            return

        print(root.data, end=" ")
        self.preOrderTraverse(root.left_child)
        self.preOrderTraverse(root.right_child)

    def InOrderTraverse(self, root):
        """中序遍历"""
        if root is None:
            return

        self.InOrderTraverse(root.left_child)
        print(root.data, end=" ")
        self.InOrderTraverse(root.right_child)

    def PostOrderTraverse(self, root):
        """后序遍历"""
        if root is None:
            return

        self.PostOrderTraverse(root.left_child)
        self.PostOrderTraverse(root.right_child)
        print(root.data, end=" ")


if __name__ == '__main__':
    tree = BinaryTree()  # 实例化树对象
    for i in range(1, 11):  # 向节点中添加元素1-10
        tree.add(i)
    print("前序遍历:", end=' ')
    tree.preOrderTraverse(tree.root)
    print()  # 换行
    print("中序遍历:", end=' ')
    tree.InOrderTraverse(tree.root)
    print()  # 换行
    print("后序遍历:", end=' ')
    tree.PostOrderTraverse(tree.root)

结果

前序遍历: 1 2 4 8 9 5 10 3 6 7 
中序遍历: 8 4 9 2 10 5 1 6 3 7 
后序遍历: 8 9 4 10 5 2 6 7 3 1 

原文链接:https://blog.csdn.net/Tonywu2018/article/details/89480282

标签:左子,遍历,python,self,访问,二叉树,root,节点
From: https://www.cnblogs.com/minqiliang/p/16825418.html

相关文章

  • script python and python interpreter
    sPython和Python解释器https://www.cnblogs.com/nickchen121/p/10722729.html目录一、Python介绍二、Python解释器发展史三、Python解释器的类型3.1CPython3.2......
  • Python命名空间(函数)
    作用域:作用范围#命名空间:划分一块区域保存所有的数据,以字典方式存储(变量与值形成映射关系)#内建命名空间:解释器启动时创建,直到解释器运行结束,生存周期最长#全局命名空......
  • Python制作自动填写脚本,100%准确率
    本次案例代码实现思路:本次案例代码实现思路:打开考试网站selenium-->浏览器驱动-->操作浏览器<模拟人的行为做操作浏览器>获取答案获取答案网站链接获取问题......
  • Linux下 Python matplotlib 包无法使用中文
    官方办法摘抄如下#firstmethodmatplotlib.rcParams['font.family']=['SourceHanSansTW','sans-serif']#secondmethodmatplotlib.rcParams['font.family']......
  • python中的单例模式
    单例模式单例模式(singletonpattern)是一种常用的软件设计模式,主要目的是确保代码运行时,某一个类只有一个实例存在。这样可以避免多次实例化同一个类,浪费内存资源。基于......
  • Python|爬取每日疫情数据并使用matplotlib绘制图像进行分析
    网页分析数据源腾讯疫情实时追踪打开网址,F12进入开发者工具(刷新一下页面),如下,所有数据都可以通过接口获取:国内数据接口:https://api.inews.qq.com/newsqa/v1/query/inn......
  • python进阶之路19 地狱入口购物车!!!!
    地狱之门##项目功能#1.用户注册#2.用户登录#3.添加购物车#4.结算购物车##项目说明#用户数据采用json格式存储到文件目录db下一......
  • python json和pickle
    json和pickle共用方法dumps把任意对象序列化成一个strloads把任意str反序列化成原来数据dump把对象序列化后写入到文件对象中load把文件对象中的内容反序列化jso......
  • python生成器
    在Python中,使用了yield的函数被称为生成器(generator)。在Python中,可以使用生成器来一次返回单个元素,从而可以避免大量占用内存。生成器的send()方法可以往生成器发送一......
  • Python3自动化打包项目发布到pypi
    效果D:\Program\Python310\python.exeD:\data\git\PythonLinuxBasicModule\upload.pyC:\Users\刘某usage:twine[-h][--version][--no-color]{register,check,upl......