題目來自Leetcoode,引用了一些題解和評論裏面的代碼翻譯成了Python·。如有侵權,請聯繫。
二叉樹的前序遍歷 ->144. 二叉樹的前序遍歷
遞歸寫法:
# 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]:
L = []
if not root:return []
def t(node):
L.append(node.val)
if node.left:
t(node.left)
if node.right :
t(node.right)
t(root)
return L
非遞歸的寫法:
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:return []
stack = [root]
L = []
while(stack):
Q = stack.pop(-1)
L.append(Q.val)
if Q.right: ######注意是先right後left
stack.append(Q.right)
if Q.left:
stack.append(Q.left)
return L
# 另外一種
if not root:return []
s = []
ans = []
node = root
while(node or s):
while(node):
ans.append(node.val) # 存根節點
s.append(node) # 爲了判斷右子樹
node = node.left # 直到最左子樹
node = s[-1].right # 最左子樹的右子樹
s.pop()
return ans
注意利用棧去存節點的時候,先right後left。因爲棧是先進後出的,如果[left,right] => pop() => [right,left]所以要先存right。
二叉樹的中序遍歷 ->94. 二叉樹的中序遍歷
遞歸版本
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:return []
L = []
def t(node):
if node.left:
t(node.left)
L.append(node.val)
if node.right:
t(node.right)
t(root)
return L
# 中序遍歷 先遍歷左子樹->根節點->右子樹
# 如果是遞歸做法則遞歸遍歷左子樹,訪問根節點,遞歸遍歷右子樹
# 非遞歸過程即:先訪問..最左子樹..結點,再訪問其父節點,再訪問其兄弟
# while循環條件 中序遍歷需先判斷當前結點是否存在,若存在則將該節點放入棧中,再將當前結點設置爲結點的左孩子,
# 若不存在則取棧頂元素[最左節點]爲cur,在訪問cur的右節點。
# 當且僅當棧空cur也爲空,循環結束。
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:return []
s = []
v = []
node = root
while(node or s):
if node :
s.append(node)
node = node.left
else:
node = s.pop(-1) # 最後一個
v.append(node.val)
node = node.right
return v
二叉樹的後序遍歷 ->145. 二叉樹的後序遍歷
遞歸版本
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:return []
L = []
def t(node):
if node.left:
t(node.left)
if node.right:
t(node.right)
L.append(node.val)
t(root)
return L
非遞歸版本
(1)輸出層次遍歷的逆
class Solution(object):
def postorderTraversal(self, root):
# 層次遍歷從左到右,從上到下 -> 隊列
# 深度遍歷從左到右,從下到上 -> 棧
# 棧:根->左->右
# output:根->右->左 層次不會變
# output[::-1]:左->右->根
if root is None:
return []
stack, output = [root, ], []
while stack:
print([node.val for node in stack])
root = stack.pop()
output.append(root.val)
if root.left is not None:
stack.append(root.left)
if root.right is not None:
stack.append(root.right)
return output[::-1]
(2)利用pre判斷右節點是否被輸出,從左到右的去遍歷。來自此處。
if not root: return []
s,v = [],[]
cur = root
pre = None
while(cur or s):
while(cur):
s.append(cur)
cur=cur.left ##遍歷左子樹
cur = s[-1]
if cur.right == None or cur.right == pre: #判斷是否該輸出結點
v.append(cur.val)
s.pop()
pre = cur
cur = None
else:
cur=cur.right
return v
二叉樹的層次遍歷
if not root:return []
q = [root]
L = []
while(q):
node=q.pop(0) #隊列,先進先出
L.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return L
二叉樹的深度 -> 面試題55 - I. 二叉樹的深度
遞歸
class Solution:
def maxDepth(self, root: TreeNode) -> int:
def t(root): O(N) O(N)
if not root:
return 0
left = t(root.left)+1
right = t(root.right)+1
return left if left>right else right
depth = t(root)
return depth
非遞歸(層次遍歷的層數)
class Solution:
def maxDepth(self, root: TreeNode) -> int:
# 層次遍歷的層數 O(N) O(N)
if not root:return 0
q = [root]
ans = 0
while(q):
ans +=1
size = len(q)
for i in range(0,size):
node = q.pop(0)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return ans