树上 DFS
在树上 [[DFS]] 是这样的一个过程:先访问根节点,然后分别访问根节点每个儿子的子树。
可以用来求出每个节点的深度、父亲等信息。
先序遍历
按照 根,左,右 的顺序遍历二叉树
void preorder(BiTree* root) {
if (root) {
cout << root->key << " ";
preorder(root->left);
preorder(root->right);
}
}
中序遍历
按照 左,根,右 的顺序遍历二叉树。
后序遍历
按照 左,右,根 的顺序遍历二叉树。
已知后序和中序,重构二叉树:build_tree(0, n, 0, n)
int border[SZ], morder[SZ];
int build_tree(int s1, int e1, int s2, int e2) {
if (s1 >= e1 || s2 >= e2) return -1; // 空树情况
int root = border[e1 - 1]; // 后序遍历的最后一个元素是根
int mid = -1;
for (int i = s2; i < e2; i++) {
if (morder[i] == root) {
mid = i;
break;
}
}
// 左子树的后序遍历起止位置和中序遍历起止位置
lch[root] = build_tree(s1, s1 + mid - s2, s2, mid);
// 右子树的后序遍历起止位置和中序遍历起止位置
rch[root] = build_tree(s1 + mid - s2, e1 - 1, mid + 1, e2);
return root;
}
update 2024/3/13
其实递归函数的参数用一个区间就可以了,然后加一个t表示当前在前序/后序的节点
int in[SZ], pre[SZ];
int n, cnt;
struct node {
int v;
node *lch, *rch;
node(int i): v(i), lch(nullptr), rch(nullptr) {}
};
//t表示当前在前序的第t个node
void buildTree(int l, int r, int &t, node* &root) {
int id = -1;
//在中序中找到根节点
for(unsigned i = l; i < r; ++i) {
if (in[i] == pre[t]) {
id = i;
break;
}
}
if (id == -1)
return;
root = new node(in[id]);
t++; //前序往后一个
if (id > l)
buildTree(l, id, t, root->lch); //取到id-1个,id是从0开始数的
if (id < r)
buildTree(id, r, t, root->rch);
}