思想
二叉樹的核心思想是分治和遞歸,特點(diǎn)是遍歷方式。
解題方式常見兩類思路:
- 遍歷一遍二叉樹尋找答案;
- 通過分治分解問題尋求答案;
遍歷分為前中后序,本質(zhì)上是遍歷二叉樹過程中處理每個(gè)節(jié)點(diǎn)的三個(gè)特殊時(shí)間點(diǎn):
- 前序是在剛剛進(jìn)入二叉樹節(jié)點(diǎn)時(shí)執(zhí)行;
- 后續(xù)是在將要離開二叉樹節(jié)點(diǎn)時(shí)執(zhí)行;
- 中序是左子樹遍歷完進(jìn)入右子樹前執(zhí)行;
# 前序
1 node
/ \
2 left 3 right
中左右
# 中序
2 node
/ \
1 left 3 right
左中右
# 后序
3 node
/ \
1 left 2 right
左右中
多叉樹只有前后序列遍歷,因?yàn)橹挥卸鏄溆形ㄒ灰淮沃虚g節(jié)點(diǎn)的遍歷
題目的關(guān)鍵就是找到遍歷過程中的位置,插入對(duì)應(yīng)代碼邏輯實(shí)現(xiàn)場(chǎng)景的目的。
實(shí)例
二叉樹的前序遍歷 leetcode 144
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
輸入:
root: TreeNode,二叉樹的根節(jié)點(diǎn)
輸出:
List[int],按照前序順序遍歷樹的所有節(jié)點(diǎn)的輸出列表
舉例:
給定二叉樹 [1,null,2,3],返回 [1,2,3].
二叉樹的數(shù)據(jù)存儲(chǔ)可以使用鏈表,也可以使用數(shù)組,往往數(shù)組更容易表達(dá),根節(jié)點(diǎn)從 index=1 處開始存儲(chǔ),浪費(fèi) index=0 的位置
left_child = 2 * parent
right_child = 2 * parent + 1
parent = child // 2
1
/ \
None 2
/ \
3 None
編碼
from typing import Optional, List
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def binary_tree_preorder_traversal_iterative(root: Optional[TreeNode]) -> List[int]:
# 初始化
result = []
iter_stack = []
if root is not None:
iter_stack.append(root)
# 遍歷
while iter_stack:
cur_node = iter_stack.pop()
result.append(cur_node.val)
if cur_node.right:
# 右子樹先壓棧,這樣才能后出棧
iter_stack.append(cur_node.right)
if cur_node.left:
iter_stack.append(cur_node.left)
return result
def binary_tree_preorder_traversal_recursive(root: Optional[TreeNode]) -> List[int]:
result = []
def traverse(root: Optional[TreeNode]):
if root is None:
return
result.append(root.val)
traverse(root.left)
traverse(root.right)
traverse(root)
return result