python实现二叉树的基本操作(非递归前中后序、层次遍历)

主要实现二叉树的非递归前序、中序、后序、层次遍历,其中二叉树的后序遍历使用了两种方法实现(一:定义一个表示量来记录该节点是否被访问;二:使用两个栈完成遍历,其思想将非递归的前序(根左右)遍历先入栈,出栈之后在放入另外一个栈之后在出栈)

'''二叉树结构的基本操作(添加元素,先序、中序、后序、层次遍历)非递归实现'''

class TreeNode(object):

    #定义树的结点内容(数据、左右孩子)
    def __init__(self,_telem,_lchild = None,_rchild = None,_flag = 0):
        self._telem = _telem
        self._lchild = _lchild
        self._rchild = _rchild
        self._flag = _flag

class Tree(object):

    #初始化一个根结点,定义一个列表存储数的结点地址
    def __init__(self,_root = None):
        self._root = _root

    #非递归创建树并且添加元素
    def tree_add(self,_elem):
        #实例化需要添加元素的结点
        node = TreeNode(_elem)
        # 如果树是空的,则对根节点赋值
        if self._root == None:
            self._root = node
        else:
            #定义一个判断列表
            queue = []
            queue.append(self._root)

            while queue:
                # 弹出队列的第一个元素
                cur = queue.pop(0)
                #判断那一个结点的哪一个孩子为空,为空则将新添加的结点的元素赋值给孩子为空的位置
                if cur._lchild == None:
                    cur._lchild = node
                    return
                elif cur._rchild == None:
                    cur._rchild = node
                    return
                else:
                    # 如果左右子树都不为空,往判断列表加入子树,循环进行子树的判断
                    queue.append(cur._lchild)
                    queue.append(cur._rchild)

    #非递归先序遍历(其利用栈的特性,先将根结点入栈,然后出栈;之后找其右子树结点入栈,出栈;左子树入栈,出栈)
    def non_recursion_preorder(self,_root):
        #判断空
        if _root == None:
            return
        else:
            #定义一个列表模仿栈的操作
            stack = []
            #将传入的结点添加进栈中
            stack.append(_root)
            #栈不为空
            while stack:
                #弹出栈的元素
                node = stack.pop()
                #打印弹出元素的内容
                print(node._telem,end=' ')
                #判断是否存在其右子树是否存在,存在则入栈,否则器左子树入栈
                if node._rchild != None:
                    stack.append(node._rchild)
                if node._lchild != None:
                    stack.append(node._lchild)

    #非递归中序遍历(通过操作栈先将左节点压入栈直到左节点为空,出栈顶元素,打印,当没有左结点时,将当前节点的右孩子赋值给_root,依次循环)
    def non_recursion_inorder(self,_root):
        #判空
        if _root == None:
            return
        # 定义一个列表进行栈的操作
        stack = []
        #循环结束条件:栈不为空,或者结点不为空
        while stack or _root != None:
            while _root != None:
                #压栈操作,继续将其左子树结点压栈
                stack.append(_root)
                _root = _root._lchild
            #进行到该位置,则说明其左结点已经不存在其左子树了;栈不为空进行出栈顶打印操作
            if stack:
                data = stack.pop()
                _root = data._rchild
                print(data._telem, end=" ")

    #非递归后序遍历(使用表示量)
    def non_recursion_postorder1(self,_root):
        #判空
        if _root == None:
            return
        #创建一个栈
        stack = []
        #对结点的左子树压栈
        stack.append(_root)
        # 变换指针(一直想左孩子往下走)
        node_root = _root._lchild
        #栈不为空或者结点存在
        while (stack or node_root):
            #结点存在
            while (node_root != None):
                #结点存在则继续压栈
                stack.append(node_root)
                #继续向左子树走
                node_root = node_root._lchild
            #左子树找完之后,出栈
            node_root = stack.pop()
            #判断其右子树是否存在,并判断是否被访问过(默认为0为访问,1为已访问)
            if (node_root._rchild != None and node_root._flag ==0):
                #进栈
                stack.append(node_root)
                #标识是否访问的标识量改变,避免重复访问
                node_root._flag = 1
                #继续找其右子树
                node_root = node_root._rchild
            else:
                #如果右结点被访问过,则打印当前结点数据
                print(node_root._telem,end=' ')
                #当前已访问到叶子结点(重置结点实现回溯过程)
                node_root = None


    #非递归后序遍历(使用两个栈实现,即使非递归前序遍历的出栈顺序在进一次栈,之后弹出)
    def non_recursion_postorder2(self,_root):
        #判断空
        if _root == None:
            return
        #定义两个栈
        stack1 = []
        stack2 = []
        #将结点加入第一个栈中
        stack1.append(_root)
        #第一个栈不为空
        while stack1:
            _root = stack1.pop()
            if _root._lchild != None:
                stack1.append(_root._lchild)
            if _root._rchild != None:
                stack1.append(_root._rchild)
            stack2.append(_root)

        while stack2:
            data = stack2.pop()
            print(data._telem,end=' ')

    # 层次遍历
    def level_traversal(self,_root):
        #判断空
        if _root == None:
            return
        #定义一个列表存储树的结点
        queue = []
        queue.append(self._root)
        #列表不为空则一直拿取
        while queue:
            #抛出列表第一个元素
            node = queue.pop(0)
            #打印
            print(node._telem,end=' ')
            #当前结点的左右结点不为空则将其添加到列表中,继续循环拿取,为空调出while循环
            if node._lchild != None:
                queue.append(node._lchild)
            if node._rchild != None:
                queue.append(node._rchild)


if __name__ == '__main__':
    tree = Tree()
    for i in range(ord('A'),ord('Z')+1):
        tree.tree_add(chr(i))
    print('非递归实现先序遍历:\n',end=' ')
    tree.non_recursion_preorder(tree._root)

    print('\n\n非递归中序遍历:\n', end=' ')
    tree.non_recursion_inorder(tree._root)

    print('\n\n非递归后序遍历(使用标识量实现):\n', end=' ')
    tree.non_recursion_postorder1(tree._root)

    print('\n\n非递归后序遍历(使用双栈实现):\n', end=' ')
    tree.non_recursion_postorder2(tree._root)

    print('\n\n层次遍历(队列实现):\n',end=' ')
    tree.level_traversal(tree._root)


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来为您解答。首先,我们需要先了解二叉树的定义和遍历方式。 二叉树是一种树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树遍历包括先序遍历、中序遍历、后序遍历和层次遍历。 先序遍历:先访问根节点,然后递归遍历左子树,最后递归遍历右子树。 中序遍历:先递归遍历左子树,然后访问根节点,最后递归遍历右子树。 后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。 层次遍历:从根节点开始,按照从上到下、从左到右的顺序依次访问每个节点。 接下来,我们来实现二叉树的建立和遍历。 ```python # 定义节点类 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right # 先序遍历(递归实现) def preorderTraversal(root): if not root: return [] res = [root.val] res += preorderTraversal(root.left) res += preorderTraversal(root.right) return res # 层次遍历非递归实现) def levelOrderTraversal(root): if not root: return [] res = [] queue = [root] while queue: node = queue.pop(0) res.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return res # 测试代码 # 创建二叉树 root = TreeNode(1) root.left = TreeNode(2) root.right = TreeNode(3) root.left.left = TreeNode(4) root.left.right = TreeNode(5) # 先序遍历 print(preorderTraversal(root)) # [1, 2, 4, 5, 3] # 层次遍历 print(levelOrderTraversal(root)) # [1, 2, 3, 4, 5] ``` 以上就是二叉树的建立和遍历的实现代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值