二叉樹遍歷是資料結構的核心基本功。本文系統整理先序、中序、後序、層次四大遍歷方式,提供遞歸與非遞歸(顯式棧/隊列)雙重實現,代碼採用現代 C++ 風格,適合教學、面試與工程參考。
struct BinaryTreeNode {
BinaryTreeNode* left;
BinaryTreeNode* right;
void* data;
};
using VisitFunc = int (*)(void*); // 訪問回調,返回非0可提前終止
// 先序:根 → 左 → 右
void preOrderR(BinaryTreeNode* root, VisitFunc visit) {
if (!root) return;
visit(root->data);
preOrderR(root->left, visit);
preOrderR(root->right, visit);
}
// 中序:左 → 根 → 右
void inOrderR(BinaryTreeNode* root, VisitFunc visit) {
if (!root) return;
inOrderR(root->left, visit);
visit(root->data);
inOrderR(root->right, visit);
}
// 後序:左 → 右 → 根
void postOrderR(BinaryTreeNode* root, VisitFunc visit) {
if (!root) return;
postOrderR(root->left, visit);
postOrderR(root->right, visit);
visit(root->data);
}
void preOrder(BinaryTreeNode* root, VisitFunc visit) {
if (!root) return;
std::stack st;
st.push(root);
while (!st.empty()) {
auto* node = st.top(); st.pop();
visit(node->data);
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
}
void inOrder(BinaryTreeNode* root, VisitFunc visit) {
std::stack st;
BinaryTreeNode* cur = root;
while (cur || !st.empty()) {
if (cur) {
st.push(cur);
cur = cur->left;
} else {
cur = st.top(); st.pop();
visit(cur->data);
cur = cur->right;
}
}
}
void postOrder(BinaryTreeNode* root, VisitFunc visit) {
std::stack st;
BinaryTreeNode *p = root, *q = nullptr;
do {
while (p) { st.push(p); p = p->left; }
q = nullptr;
while (!st.empty()) {
p = st.top(); st.pop();
if (!p->right || p->right == q) {
visit(p->data);
q = p;
} else {
st.push(p);
p = p->right;
break;
}
}
} while (!st.empty());
}
void levelOrder(BinaryTreeNode* root, VisitFunc visit) {
if (!root) return;
std::queue q;
q.push(root);
while (!q.empty()) {
auto* node = q.front(); q.pop();
visit(node->data);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
| 遍歷 | 前驅 | 後繼 |
|---|---|---|
| 中序 | 左子樹最右下節點 | 右子樹最左下節點 |
| 後序 | — | 若為根則無;若為右子或左子且無右兄則為父;否則為右子樹後序首節點 |
10⁴ 可能棧溢位;生產環境深樹優先用非遞歸熟練掌握這四種遍歷的遞歸與非遞歸寫法,是解決二叉樹絕大多數問題(序列化、重建、LCA、路徑和等)的基石。