数据结构-二叉树-二叉树的遍历

二叉树的遍历

线性数组或链表只能单向从头到尾遍历或者反向遍历。所谓二叉树的遍历简单的来说就是访问树中所有的节点各一次,并且在遍历后,将树中的数据转化为线性关系。二叉树可以将每个节点分为左右两个分支

二叉树的特性一律从左向右遍历,那么遍历的方式就分为了三种,分别是

  • 中序遍历:左子树->树根->右子树
  • 前序遍历:树根->左子树->右子树
  • 后序遍历:左子树->右子树->树根

这三种方式的顺序也十分好记,简单来说“从左向右,树根最牛”,意思就是所有遍历的顺序都是从左向右,树根在哪个位置,就属于什么遍历,树根在前面就是前序遍历,树根在中间就属于中序遍历,树根在后面就属于后序遍历

下面分别介绍三种方式遍历的算法实现

  • 中序遍历

    中序遍历的顺序就是:左子树->树根->右子树

    就是从树的左侧逐步向下方移动,直到无法移动,再访问此节点,并向右移动一个节点。如果无法向右移动,就可以返回上层的父节点,然后重复这个步骤

    • 遍历左子树
    • 遍历树根
    • 遍历右子树

    这种方式可以采用递归的方法,递归找到最左侧的节点,然后找到右侧,最后找到树根,出口就是节点为空时

    """
    中序遍历
    """
    def inorder(ptr):
        if ptr != None:
            inorder(ptr.left)
            print('[%2d]' % ptr.data,end='')
            inorder(ptr.right)
    
  • 后序遍历

    后序遍历的顺序就是:左子树->右子树->树根

    即是先遍历左子树,再遍历右子树,最后遍历根节点,反复重复这个步骤

    • 遍历左子树
    • 遍历右子树
    • 遍历树根
    """
    后序遍历
    """
    def postorder(ptr):
        if ptr != None:
            postorder(ptr.left)
            postorder(ptr.right)
            print('[%2d]' % ptr.data,end='')
    
  • 前序遍历

    前序遍历的顺序就是:树根->左子树->右子树

    就是先从根节点遍历,再往左方移动,当无法移动时继续右方移动,接着重复执行此步骤

    • 遍历树根
    • 遍历左节点
    • 遍历右节点
    """
    前序遍历
    """
    def preorder(ptr):
        if ptr != None:
            print('[%2d]' % ptr.data,end='')
            preorder(ptr.left)
            preorder(ptr.right)
    

    总结一下:

    三种遍历方法的算法实现所需要实现的功能类似,只是步骤过程有先后,都是遍历左子树和右子树,不同的地方是看在哪一步之后做出处理

    这个递归算法的运行过程细节以中序为例:

    """
    中序遍历
    """
    def inorder(ptr):
        """
        判断此节点是否为空,不为空进入,如果第一个节点就为空,说明二叉树为空
        """
        if ptr != None:   
            """
            将下一个左节点调用此函数,为空说明是子树的最左侧,不为空继续将一下个左节点调用,直至找到最左侧
            """
            inorder(ptr.left)       
            """
            执行了上述代码,找到了最左侧的节点,输出该节点
            """
            print('[%2d]' % ptr.data,end='')    
            """
            找下一个右节点,注意,执行到这一步,左、中节点已经输出,所以找右节点
            """
            inorder(ptr.right)      
    

    因为二叉树的规则是:左子树 < 根节点 < 右子树

    所以使用中序遍历会发现输出的结果已经完成了从小到大的排序

    例子:设计程序,中序、后序、前序遍历二叉树

    class tree:
        def __init__(self):
            self.data = 0
            self.left = None
            self.right = None
    
    """
    中序遍历
    """
    def inorder(ptr):
        if ptr != None:
            inorder(ptr.left)
            print('[%2d]' % ptr.data,end='')
            inorder(ptr.right)
    
    """
    后序遍历
    """
    def postorder(ptr):
        if ptr != None:
            postorder(ptr.left)
            postorder(ptr.right)
            print('[%2d]' % ptr.data,end='')
    
    """
    前序遍历
    """
    def preorder(ptr):
        if ptr != None:
            print('[%2d]' % ptr.data,end='')
            preorder(ptr.left)
            preorder(ptr.right)
    
    """
    建立二叉树
    """
    def create_tree(root,val):
        newnode = tree()
        newnode.data = val
        newnode.left = None
        newnode.right = None
        if root == None:
            root = newnode
            return root
        else:
            current = root
            while current != None:
                backup = current
                if current.data > val:
                    current = current.left
                else:
                    current = current.right
            if backup.data > val:
                backup.left = newnode
            else:
                backup.right = newnode
        return root
    
    """
    主程序
    """
    data = [5,6,24,8,12,3,17,1,9]
    ptr = None
    root = None
    for i in range(9):
        ptr = create_tree(ptr,data[i])
    print("--------------------------")
    print("中序遍历")
    inorder(ptr)
    print('')
    print('后序遍历')
    postorder(ptr)
    print('')
    print('前序遍历')
    preorder(ptr)
    

    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牧码文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值