# 如何根據前序遍歷和中序遍歷創建Python二叉樹
## 目錄
1. [二叉樹基礎概念](#二叉樹基礎概念)
2. [前序遍歷與中序遍歷的特性](#前序遍歷與中序遍歷的特性)
3. [重建二叉樹的算法原理](#重建二叉樹的算法原理)
4. [Python實現步驟詳解](#Python實現步驟詳解)
5. [完整代碼實現](#完整代碼實現)
6. [復雜度分析與優化](#復雜度分析與優化)
7. [實際應用場景](#實際應用場景)
8. [常見問題解答](#常見問題解答)
## 二叉樹基礎概念
二叉樹(Binary Tree)是每個節點最多有兩個子節點的樹結構,通常稱為左子節點和右子節點。二叉樹在計算機科學中有廣泛應用,如:
- 數據庫索引(B樹/B+樹)
- 文件系統目錄結構
- 高效搜索(二叉搜索樹)
- 表達式樹
基本術語:
- **根節點**:沒有父節點的頂層節點
- **葉子節點**:沒有子節點的節點
- **深度**:從根到節點的路徑長度
- **高度**:從節點到最深葉子節點的路徑長度
```python
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
訪問順序:根節點 → 左子樹 → 右子樹
示例二叉樹:
1
/ \
2 3
/ \
4 5
前序遍歷結果:[1, 2, 4, 5, 3]
訪問順序:左子樹 → 根節點 → 右子樹
相同示例的中序遍歷結果:[4, 2, 5, 1, 3]
給定: - 前序遍歷 preorder = [3,9,20,15,7] - 中序遍歷 inorder = [9,3,15,20,7]
構建過程: 1. 根節點是3(前序第一個) 2. 在中序中找到3: - 左子樹中序:[9] - 右子樹中序:[15,20,7] 3. 根據左子樹長度1,劃分前序: - 左子樹前序:[9] - 右子樹前序:[20,15,7] 4. 遞歸處理左右子樹
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def buildTree(preorder, inorder):
if not preorder or not inorder:
return None
root_val = preorder[0]
root = TreeNode(root_val)
# 找到中序遍歷中的根節點位置
root_pos = inorder.index(root_val)
# 遞歸構建左右子樹
root.left = buildTree(preorder[1:1+root_pos], inorder[:root_pos])
root.right = buildTree(preorder[1+root_pos:], inorder[root_pos+1:])
return root
使用哈希表加速查找:
def buildTree(preorder, inorder):
inorder_map = {val: idx for idx, val in enumerate(inorder)}
def helper(pre_start, pre_end, in_start, in_end):
if pre_start > pre_end:
return None
root_val = preorder[pre_start]
root = TreeNode(root_val)
root_pos = inorder_map[root_val]
left_size = root_pos - in_start
root.left = helper(pre_start+1, pre_start+left_size,
in_start, root_pos-1)
root.right = helper(pre_start+left_size+1, pre_end,
root_pos+1, in_end)
return root
return helper(0, len(preorder)-1, 0, len(inorder)-1)
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def buildTree(preorder, inorder):
# 創建中序遍歷值到索引的哈希映射
inorder_map = {val: idx for idx, val in enumerate(inorder)}
def array_to_tree(pre_start, pre_end, in_start, in_end):
# 遞歸終止條件
if pre_start > pre_end:
return None
# 前序遍歷的第一個值是根節點
root_val = preorder[pre_start]
root = TreeNode(root_val)
# 在中序遍歷中找到根節點位置
root_pos = inorder_map[root_val]
# 計算左子樹的節點數
left_size = root_pos - in_start
# 遞歸構建左右子樹
root.left = array_to_tree(
pre_start + 1, # 前序左子樹開始
pre_start + left_size, # 前序左子樹結束
in_start, # 中序左子樹開始
root_pos - 1 # 中序左子樹結束
)
root.right = array_to_tree(
pre_start + left_size + 1, # 前序右子樹開始
pre_end, # 前序右子樹結束
root_pos + 1, # 中序右子樹開始
in_end # 中序右子樹結束
)
return root
return array_to_tree(0, len(preorder)-1, 0, len(inorder)-1)
# 測試代碼
def printInorder(root):
if root:
printInorder(root.left)
print(root.val, end=' ')
printInorder(root.right)
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
tree = buildTree(preorder, inorder)
printInorder(tree) # 輸出: 9 3 15 20 7
序列化/反序列化二叉樹:
編譯器設計:
數據庫系統:
生物信息學:
單種遍歷無法唯一確定樹結構。例如: - 前序[1,2]可能是:
1 1
\ /
2 2
當樹中存在重復值時: 1. 需要額外的信息(如節點ID) 2. 或限制為二叉搜索樹(BST)
使用棧模擬遞歸過程:
def buildTree(preorder, inorder):
if not preorder:
return None
root = TreeNode(preorder[0])
stack = [root]
inorder_idx = 0
for i in range(1, len(preorder)):
node = stack[-1]
if node.val != inorder[inorder_idx]:
node.left = TreeNode(preorder[i])
stack.append(node.left)
else:
while stack and stack[-1].val == inorder[inorder_idx]:
node = stack.pop()
inorder_idx += 1
node.right = TreeNode(preorder[i])
stack.append(node.right)
return root
可以,原理類似: - 后序遍歷的最后一個元素是根節點 - 同樣用中序遍歷劃分左右子樹
通過本文,您應該已經掌握了: 1. 二叉樹的基本概念 2. 前序/中序遍歷的特性 3. 重建二叉樹的算法原理 4. Python實現的具體方法 5. 優化思路和實際應用
建議讀者嘗試擴展實現: - 后序+中序重建 - 處理重復元素的情況 - 非遞歸實現版本 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。