二叉树算法实战:美国血统重建与深度宽度计算
一、美国血统 (American Heritage)
题目描述
给定一棵二叉树的中序遍历序列和先序遍历序列,要求输出其后序遍历序列。这是经典的树重建问题,核心在于理解不同遍历顺序中根节点的位置特征。
算法思路
解法的关键在于递归划分区间。先序遍历的第一个元素必然是当前子树的根节点。在中序遍历中找到这个根节点,其左侧即为左子树的中序序列,右侧为右子树的中序序列。根据左右子树的长度,可以在先序序列中对应划分出左右子树的范围。通过递归处理左右子树,最后访问根节点,即可得到后序遍历结果。
具体步骤如下:
- 确定当前子树的根节点(先序序列的首位)。
- 在中序序列中定位根节点,以此分割左右子树区间。
- 递归处理左子树和右子树。
- 输出根节点值。
代码实现
#include <iostream>
#include <string>
using namespace std;
string a, b; // a: 中序,b: 先序
void dfs(int l1, int r1, int l2, int r2) {
if (l1 > r1) return;
// 寻找中序遍历中根节点的位置
int p = l1;
while (a[p] != b[l2]) p++;
// 递归处理左子树
// 左子树中序范围:[l1, p-1]
// 左子树先序范围:[l2+1, l2 + (p - l1)]
dfs(l1, p - 1, l2 + 1, l2 + p - l1);
// 递归处理右子树
// 右子树中序范围:[p+1, r1]
// 右子树先序范围:[l2 + p - l1 + 1, r2]
dfs(p + 1, r1, l2 + p - l1 + 1, r2);
// 根节点(后序遍历顺序:左 -> 右 -> 根)
cout << b[l2];
}
int {
cin >> a >> b;
(, a.() - , , b.() - );
;
}


