遍历二叉树,一篇博客就够了

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yinhui_zhang/article/details/88558674

       讲在前面的话,网上一搜遍历二叉树出来的结果真的是良莠不齐,简直不能忍啊,很多前序、中序、后序遍历分别用三个结构不一样的算法来描述,这谁能顶得住啊!!!遍历二叉树代码,看一篇博客就够了。

1.二叉树遍历分类:

  一般我们二叉树分为前序、中序、后序遍历(说明:本文不包括层次遍历),假设用L、D、R分别表示遍历左子树、访问根节点、遍历右子树,前序、中序、后序遍历可以分别表示为DLR、LDR、LRD(一定要记住这个顺序,在后面的代码中很重要!!)。

  算法一般分为递归版本和迭代版本,下面都给出这两个版本的python代码,所有代码都测试通过。

2.talk is easy, show me the code

2.1递归版的二叉树前序、中序、后序遍历

前序遍历:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)

中序遍历:

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

后序遍历:

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) +  [root.val] 

发现规律没,只需要改变在代码中改变L、D、R的操作就可以了(开头已经定义过的)。

2.2迭代版的二叉树前序、中序、后序遍历

非递归的二叉树遍历思想主要是用栈和标志来不断的压栈和退栈,自己照着代码压一次栈就什么都明白了。

前序遍历:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        stack = []
        stack.append((0, root))
        res = []
        while len(stack) != 0:
            flag, node = stack.pop()
            if node is None:
                continue
            if flag == 1:
                res.append(node.val)
            else:
                stack.append((0, node.right)) #DLR right最先压入堆栈,然后依次是LD
                stack.append((0, node.left))
                stack.append((1, node))
        return res 

中序遍历:

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        stack = []
        stack.append((0, root))
        res = []
        while len(stack) != 0:
            flag, node = stack.pop()
            if node is None:
                continue
            if flag == 1:
                res.append(node.val)
            else:
                stack.append((0, node.right)) #LDR right最先压入堆栈,然后依次是DL
                stack.append((1, node))
                stack.append((0, node.left))
        return res

后序遍历:

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        stack = []
        stack.append((0, root))
        res = []
        while len(stack) != 0:
            flag, node = stack.pop()
            if node is None:
                continue
            if flag == 1:
                res.append(node.val)
            else:
                stack.append((1, node))      #LRD D最先压入堆栈,然后依次是RL
                stack.append((0, node.right))
                stack.append((0, node.left))
            
        return res

又发现规律没,只需要改变最后stack的压入的顺序就可以应付三种遍历算法,简直完美。秒杀其他算法。

猜你喜欢

转载自blog.csdn.net/yinhui_zhang/article/details/88558674