二叉树N叉数的前中后序遍历总结,python实现递归法和迭代法
關于二叉樹的前序遍歷(preoder)、中序遍歷(inorder)和后序遍歷(postorder),實際上只需要記住:左子節點一定在右子節點的左邊(左右),所謂前中后序遍歷就是根節點的位置不同,前序是根左右,中序是左根右,后序是左右根。
python代碼實現,先定義樹節點的類如下:
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right然后是前中后序的遞歸法實現,非常直觀:
# 前序遍歷def preorderTraversal(self, root: TreeNode) -> List[int]:def preorder(root: TreeNode):if not root:returnans.append(root.val) # 根左右preorder(root.left)preorder(root.right)ans = list()preorder(root)return ans# 中序遍歷def inorderTraversal(self, root: TreeNode) -> List[int]:def inorder(root: TreeNode):if not root:returninorder(root.left) # 左根右ans.append(root.val)inorder(root.right)ans = list()inorder(root)return ans# 后序遍歷def postorderTraversal(self, root: TreeNode) -> List[int]:def postorder(root: TreeNode):if not root:returnpostorder(root.left) # 左右根postorder(root.right)ans.append(root.val)ans = list()postorder(root)return ans可以看到,實際上前中后序的遞歸法實現區別僅僅在于訪問左右子節點和將根節點加入結果數組的順序不同。
迭代法實現復雜一點,一般是使用一個棧,如下:
# 前序遍歷def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:if node.right: # 右stack.append(node.right)if node.left: # 左stack.append(node.left)stack.append(node) # 根stack.append(None)else:node = stack.pop()ans.append(node.val)return ans# 中序遍歷def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:if node.right: # 右stack.append(node.right)stack.append(node) # 根stack.append(None)if node.left: # 左stack.append(node.left)else:node = stack.pop()ans.append(node.val)return ans# 后序遍歷def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:stack.append(node) # 根stack.append(None)if node.right: # 右stack.append(node.right)if node.left: # 左stack.append(node.left)else:node = stack.pop()ans.append(node.val)return ans可以看到,前中后序遍歷的迭代寫法是統一的,唯一區別就是中間的代碼,只需要記住從下往上是根左右(前序)、左根右(中序)、左右根(后序)即可。
對于N叉數,思路和二叉樹是比較相似的。先看下N叉數的樹節點定義:
# Definition for a Node. class Node:def __init__(self, val=None, children=None):self.val = valself.children = children589. N 叉樹的前序遍歷
class Solution:def preorder(self, root: 'Node') -> List[int]:def preorderTravel(root: 'Node'):if not root:returnans.append(root.val)for child in root.children:preorderTravel(child)ans = list()preorderTravel(root)return ans遞歸寫法,區別只是用for循環遍歷所有子節點,而不是只遍歷左右子節點。
class Solution:def preorder(self, root: 'Node') -> List[int]:if not root:return []stack = [root,]output = [] while stack:root = stack.pop()output.append(root.val)stack.extend(root.children[::-1])return output迭代寫法,這里注意入棧的是root.children[::-1],這樣出棧時才是從左子樹到右子樹正確的順序。
590. N 叉樹的后序遍歷
class Solution:def postorder(self, root: 'Node') -> List[int]:def postorderTravel(root: 'Node'):if not root:returnfor child in root.children:postorderTravel(child)ans.append(root.val)ans = list()postorderTravel(root)return ans遞歸寫法,相比前序遍歷只是交換了一下位置,而N叉數沒有中序遍歷。
class Solution:def postorder(self, root: 'Node') -> List[int]:if not root:return []stack = [root,]output = []while stack:root = stack.pop()if root:output.append(root.val)for child in root.children:stack.append(child)return output[::-1]迭代寫法。
559. N 叉樹的最大深度
class Solution:def maxDepth(self, root: 'Node') -> int:if not root:return 0elif root.children == []:return 1else:temp = list()for child in root.children:temp.append(self.maxDepth(child))return max(temp) + 1遞歸,與二叉樹的最大深度類似,注意要判斷 root.children == [] 時深度為1。
還有一種遍歷二叉樹的方法,可以將空間復雜度降至O(1),名為Morris遍歷,對其解釋地最好的我覺得是這篇文章。
另外還有一種題,二叉樹是存儲成數組形式的,這時就要利用以下關系:根節點從0開始編號,對于任意一個節點 i,其左孩子編號為 2i+1,右孩子編號為 2i+2,代碼如下:
# # 對給定的二叉樹依次完成前序,中序,后序遍歷,并輸出遍歷結果 # @param input int整型一維數組 -1表示Nil節點 # @return int整型二維數組 # # 定義一個二維列表 results = [[]for i in range(3)] class Solution:def binaryTreeScan(self , input ):# write code here# 前序遍歷def preOrder(root):if root<len(input):if input[root]!=-1:results[0].append(input[root])preOrder(root*2+1)preOrder(root*2+2)# 中序遍歷def inOrder(root):if root<len(input):inOrder(root*2+1)if input[root]!=-1:results[1].append(input[root])inOrder(root*2+2)# 后序遍歷def postOrder(root):if root<len(input):postOrder(root*2+1)postOrder(root*2+2)if input[root]!=-1:results[2].append(input[root])preOrder(0)inOrder(0)postOrder(0)return results總結
以上是生活随笔為你收集整理的二叉树N叉数的前中后序遍历总结,python实现递归法和迭代法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab常用函数辨析
- 下一篇: 二叉树层序遍历(广度优先搜索)基础概念与