*****144-94-145-102 二叉树的前序、中序、后序、层序遍历

前序--中序--后序--层序 遍历的递归与迭代算法实现。递归版本很简单直观。前三种迭代版本用栈实现层序遍历用队列实现

给定一个二叉树,返回它的 前序 遍历。

 示例:

输入: [1,null,2,3]  
   1
    \
     2
    /
   3 

前序:[1,2,3]    中序:[1 3 2]   后序: [3 2 1]

 

1. 前序遍历:

竟然又找到了一行代码解决方案!:

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

 

递归:

 1 class Solution:
 2     def preorderTraversal(self, root: TreeNode) -> List[int]:
 3         if not root: return []
 4         res = []
 5         if not root.left and not root.right:
 6             return [root.val]
 7         res.append(root.val)
 8         res += self.preorderTraversal(root.left)
 9         res += self.preorderTraversal(root.right)
10         return res

递归:

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def dfs(self, root, res):
10         if not root:return 
11         res.append(root.val)
12         self.dfs(root.left, res)
13         self.dfs(root.right, res)
14     
15     
16     def preorderTraversal(self, root: TreeNode) -> List[int]:
17         res = []
18         self.dfs(root, res)
19         return res

迭代:

begin

根节点进栈

while 栈不为空:

          栈顶元素出栈

          该元素右孩子进栈

          该元素左孩子进栈

end

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     
10     def preorderTraversal(self, root: TreeNode) -> List[int]:
11         if not root: return []
12         stack = [root]
13         res = []
14         while(stack):
15             top = stack.pop()
16             if top:
17                 res.append(top.val)
18                 stack.append(top.right)
19                 stack.append(top.left)
20         return res

 

2. 中序遍历:

递归:

 

 1 class Solution:
 2     def inorderTraversal(self, root: TreeNode) -> List[int]:
 3         if not root:return []
 4         res = []
 5         if not root.left and not root.right:
 6             return [root.val]
 7         res+=self.inorderTraversal(root.left)
 8         res.append(root.val)
 9         res+=self.inorderTraversal(root.right)
10         return res

 

递归:

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def dfs(self,root, res):
10         if not root:return 
11         self.dfs(root.left, res)
12         res.append(root.val)
13         self.dfs(root.right, res)
14     
15     def inorderTraversal(self, root: TreeNode) -> List[int]:
16         res = []
17         self.dfs(root, res)
18         return res

迭代:通过在纸上画出遍历过程可以得到这个规律:

begin

根节点进栈

while 栈不为空:

         以栈的顶点为根节点,一直遍历其左孩子,即不断另左孩子进栈

         元素一直出栈,直到当前出栈的元素有右孩子,此时停止出栈,将这个右孩子进栈

end

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def inorderTraversal(self, root: TreeNode) -> List[int]:
10         if not root:return []
11         temp = [root]
12         res = []
13         while(temp):
14             root = temp[-1]
15             while(root.left):
16                 temp.append(root.left)
17                 root = root.left
18             while(temp):
19                 top = temp.pop()
20                 res.append(top.val)
21                 if top.right:
22                     temp.append(top.right)
23                     break
24         return res

leetcode的其他写法:

def inorderTraversal(self, root):
    res, stack = [], []
    while True:
        while root:
            stack.append(root)
            root = root.left
        if not stack:
            return res
        node = stack.pop()
        res.append(node.val)
        root = node.right
View Code
def inorderTraversal(self, root):
    ans = []
    stack = []
    
    while stack or root:
        if root:
            stack.append(root)
            root = root.left
        else:
            tmpNode = stack.pop()
            ans.append(tmpNode.val)
            root = tmpNode.right
        
    return ans
View Code

 

3. 后序遍历:

递归:

 

 1 class Solution:
 2     def postorderTraversal(self, root: TreeNode) -> List[int]:
 3         if not root:return []
 4         res = []
 5         if not root.left and not root.right:
 6             return [root.val]
 7         res+=self.postorderTraversal(root.left)
 8         res+=self.postorderTraversal(root.right)
 9         res.append(root.val)
10         return res

 

递归:

 

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def dfs(self,root, res):
10         if not root:return
11         self.dfs(root.left, res)
12         self.dfs(root.right, res)
13         res.append(root.val)
14         
15     def postorderTraversal(self, root: TreeNode) -> List[int]:
16         res = []
17         self.dfs(root, res)
18         return res

迭代:虽然在leetcode上后序标记为hard。其实和前序遍历几乎一样!比中序还简单!!!思路如下:

begin

根节点进栈

while 栈不为空:

          栈顶元素出栈

          该元素左孩子进栈

          该元素右孩子进栈

翻转结果

end

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def postorderTraversal(self, root: TreeNode) -> List[int]:
10         if not root:return []
11         temp = [root]
12         res = []
13         while(temp):
14             top = temp.pop()
15             res.append(top.val)
16             if top.left:
17                 temp.append(top.left)
18             if top.right:
19                 temp.append(top.right)
20         return res[::-1]

 

4. 层序遍历:

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

递归:

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def bfs(self, root, res):
10         temp = []
11         level = []
12         for curr in root:            # root代表当前level中的元素
13             if curr.left:
14                 level.append(curr.left)       # level存储下一level的元素
15             if curr.right:
16                 level.append(curr.right)
17             temp.append(curr.val)
18         res.append(temp)
19         if not level:     # 终止条件:下一level再无元素
20             return
21         self.bfs(level, res)
22         
23 
24     def levelOrder(self, root: TreeNode) -> List[List[int]]:
25         res = []
26         if root:
27             self.bfs([root],res)
28         return res

迭代:因为返回结果是要按照层次存储的,并非直接放在一个单列表中,所以我们需要对层进行操作。

begin

根节点进队作为第一层

while 当前层不为空

          将当前层所有元素出队

          对于当前层的每个元素都令其左右孩子进队

          只保留非空结点在队中

end

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def levelOrder(self, root: TreeNode) -> List[List[int]]:
10         if not root:return []
11         res, level = [], [root]
12         while(level):
13             res.append([node.val for node in level])
14             temp = []
15             for node in level:
16                 temp.extend([node.left,node.right])
17             level = [node for node in temp if node]
18         return res

 

def PrintFromTopToBottom(self, root):
        if not root:
            return []
        currentStack = [root]
        res = []
        while currentStack:
            nextStack = []
            for i in currentStack:
                if i.left: nextStack.append(i.left)
                if i.right: nextStack.append(i.right)
                res.append(i.val)
            currentStack = nextStack
        return res

我的另一种写法:

 1 class Solution:
 2     def levelOrder(self, root: TreeNode) -> List[List[int]]:
 3         if not root:return []
 4         res,pre_level = [], [root]           # pre_level表示上一层的所有节点
 5         while(pre_level):
 6             curr_level = []                  # curr_level表示当前层所有节点
 7             temp = []
 8             for curr in pre_level:
 9                 temp.append(curr.val)
10                 if curr.left:
11                     curr_level.append(curr.left)
12                 if curr.right:
13                     curr_level.append(curr.right)
14             res.append(temp)  
15             pre_level = curr_level          #  更新当前层为上一层
16         return res

leetcode类似写法:

 1 from collections import deque
 2 class Solution:
 3     def levelOrder(self, root):
 4         if not root: return []
 5         queue, res = deque([root]), []
 6         
 7         while queue:
 8             cur_level, size = [], len(queue)
 9             for i in range(size):
10                 node = queue.popleft()
11                 if node.left:
12                     queue.append(node.left)
13                 if node.right:
14                     queue.append(node.right)
15                 cur_level.append(node.val)
16             res.append(cur_level)
17         return res
View Code

 

posted @ 2019-05-11 20:40  三年一梦  阅读(217)  评论(0)    收藏  举报