1.前序/中序/後序/層序遍歷(非遞歸版本)
遞歸版本見註釋部分代碼
迭代方法使用棧。當前訪問的節點一定是棧頂的節點(都是先將根節點入棧),先取出,再按照遍歷順序將其他節點入棧。
根據下面這個模板來思考:
while 棧非空 or p非空:
if p 非空:
xxxxxxx
else:
xxxxxxx
①前序遍歷
這個方法是先讀取根節點結果,右子樹、左子樹分別入棧,出棧輸出結果則是根->左->右
class Solution:
# def __init__(self):
# self.res = []
def preorderTraversal(self, root: TreeNode) -> List[int]:
# 遞歸
# if root:
# self.res.append(root.val)
# self.preorderTraversal(root.left)
# self.preorderTraversal(root.right)
# return self.res
# 棧
res = []
if not root: return res
s = [root]
while s:
node = s.pop()
res.append(node.val)
if node.right: s.append(node.right)
if node.left: stack.append(node.left)
return res
② 中序遍歷
只對根節點做出入棧的處理。根先入棧,遍歷左子樹,根出棧,遍歷右子樹,則輸出結果爲左->根->右。
class Solution:
# def __init__(self):
# self.res = []
def inorderTraversal(self, root: TreeNode) -> List[int]:
# if root:
# self.inorderTraversal(root.left)
# self.res.append(root.val)
# self.inorderTraversal(root.right)
# return self.res
# 棧
res = []
if not root :return res
s = []
while s or root:
if root:
s.append(root)
root = root.left
else:
root = s.pop()
res.append(root.val)
root = root.right
return res
③後序遍歷
巧妙借用前序的思想,先讀取根節點結果,左子樹、右子樹依次入棧,則輸出爲根->右->左,最後將輸出逆序就能生成正確的後序輸出:左->右->根。
class Solution:
# def __init__(self):
# self.res = []
def postorderTraversal(self, root):
# 遞歸
# if root:
# self.postorderTraversal(root.left)
# self.postorderTraversal(root.right)
# self.res.append(root.val)
# return self.res
# 棧
res = []
if not root: return res
s = [root]
while s:
node = s.pop()
res.append(node.val)
if node.left: s.append(node.left)
if node.right: s.append(node.right)
return res[::-1]
④ 層序遍歷
用隊列的方法,每次訪問隊首節點,並將其左、右子樹入隊。
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
res = []
if not root: return res
q = [root]
while q:
level = []
n = len(q)
for i in range(n):
level.append(q[i].val)
if q[i].left: q.append(q[i].left)
if q[i].right: q.append(q[i].right)
q = q[n:]
res.append(level)
level = []
return res
2.遞歸方法中的自頂向下 / 自底向上
舉例:求二叉樹最大深度
① 自頂向下( 通過函數傳值的方法,從頂層傳到底層)
class Solution:
def _maxDepth(self, root, depth):
if not root: return depth-1
l_depth = self._maxDepth(root.left,depth+1)
r_depth = self._maxDepth(root.right,depth+1)
return max(l_depth,r_depth)
def maxDepth(self, root: TreeNode) -> int:
if not root: return 0
return self._maxDepth(root,1)
② 自底向上
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root: return 0
l_depth = self.maxDepth(root.left)
r_depth = self.maxDepth(root.right)
return max(l_depth,r_depth)+1