UVA 536 - Tree Recovery(二叉树重建)

本文介绍如何通过给定的前序和中序遍历序列重构二叉树,并实现后序遍历输出。利用递归方法确定每个节点的左右子树,最终完成二叉树的重建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接

思路: 二叉树有三种遍历方式, 体现在代码中, 就是:保存结点值如果是在递归前保存, 就是前序, 在递归完左子树后保存, 就是中序, 递归完左右子树后保存就是后序。

由中序加上另一种, 我们可以写出剩下一种。   由前序遍历或者后序遍历, 我们可以依次知道父结点是什么, 然后在中序遍历中找到对应值, 那么该结点的左右子树分别在中序遍历中该位置的左右。 递归解决即可。

细节参见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 100;
int T,n,m,len,cnt = 1;
char s1[maxn], s2[maxn];
struct node {
    node *ch[2];
    char v;
    node(char v):v(v) {
        ch[0] = ch[1] = NULL;
    }
} *root;
void dfs(node* &u, int pos, int l, int r) {
    if(l > r) return ;
    for(int i = l; i <= r; i++) {
        if(s2[i] == s1[pos]) {
            u = new node(s1[pos]);
            if(l >= r) return ;
            if(l <= i-1) dfs(u->ch[0], ++cnt, l, i-1);
            if(i+1 <= r) dfs(u->ch[1], ++cnt, i+1, r);
            return ;
        }
    }
}
vector<char> ans;
void rebuild(node* u) {
    if(u == NULL) return ;
    rebuild(u->ch[0]);
    rebuild(u->ch[1]);
    ans.push_back(u->v);
}
void remove_tree(node* &u) {
    if(u->ch[0] != NULL) remove_tree(u->ch[0]);
    if(u->ch[1] != NULL) remove_tree(u->ch[1]);
    delete u;
    u = NULL;
}
int main() {
    while(~scanf("%s%s",s1+1, s2+1)) {
        len = strlen(s1+1);
        cnt = 1;
        dfs(root, 1, 1, len);
        ans.clear();
        rebuild(root);
        int len = ans.size();
        for(int i = 0; i < len; i++) {
            printf("%c", ans[i]);
        }
        printf("\n");
        remove_tree(root);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值