C++完整参考代码
#include <iostream>
#include <string>
using namespace std;
struct node {
char data;
node *left, *right;
node(char d) : data(d), left(nullptr), right(nullptr) {}
};
// 由先序 pre[l1..r1] 与中序 in[l2..r2] 建树
node* build(const string& pre, int l1, int r1,
const string& in, int l2, int r2) {
if (l1 > r1) return nullptr;
char root = pre[l1]; // 先序的第一个就是根
int k = in.find(root); // 根在中序中的位置
int len = k - l2; // 左子树的结点个数
node* p = new node(root);
p->left = build(pre, l1 + 1, l1 + len, in, l2, k - 1);
p->right = build(pre, l1 + len + 1, r1, in, k + 1, r2);
return p;
}
void postOrder(node* t) { // 后序:左 → 右 → 根
if (!t) return;
postOrder(t->left);
postOrder(t->right);
cout << t->data << " ";
}
int main() {
string pre = "124536"; // 先序序列
string in = "425136"; // 中序序列
node* root = build(pre, 0, pre.size() - 1, in, 0, in.size() - 1);
cout << "后序遍历:";
postOrder(root);
cout << endl; // 后序遍历:4 5 2 6 3 1
return 0;
}
答案:后序序列是 4 5 2 6 3 1。
思路:先序的第一个数 1 一定是根;到中序里找 1,它左边 4 2 5 是左子树、右边 3 6 是右子树。对左右两棵子树重复同样的操作(先序里接着的数就是子树的根,中序负责把子树再分成左右两半),最后按"左 → 右 → 根"输出,就得到后序 4 5 2 6 3 1。顺便一提,这棵树的层序是 1 2 3 4 5 6。
考点:由先序遍历 + 中序遍历唯一确定一棵二叉树、三种遍历的相互关系。
易错:① 记住套路"先序找根、中序分左右";② 递归时区间边界容易差一位(左子树先序是 l1+1 ~ l1+len);③ 后序是最后才输出根,所以根 1 排在最后一个。