刘汝佳第六章UVA-548

递归遍历树还是有点绕。现在看来是这样
1.先序遍历的结果,第一个为节点,然后一坨是PreOrder(left[root])的结果,右边是PreOrder(right[root])的结果
2.中序遍历,同理,节点在中间。
3.后序遍历,同理,节点在最后

在这道题中,因为要区分节点,所以每个节点权值不一样,所以可以用节点的权值来唯一表征节点。总的来说:
1.用数组实现了树,left[root]是root左边的权值,right[root]是root右边的权值。
2.build函数写的很好,l1和r1代表了构建树所需要的inorder的范围,包括InOrder(left[root]),root,InOrder(right[root])。l2和r2代表了构建树所需要的PostOrder的范围。我们要做的事情,就是把利用PostOrder来把root找到,然后在InOrder中分出左边和右边,在进行下一次构建。而这个递归的出口条件,就是范围为0,即l1>r1. 因为build是返回所需构建范围中的结点,所以当终值的时候,返回0,即0即为接地。这就要满足不存在零权值的节点了。
3.更多的细节,比如读入数据,边界是多少,还需要更加熟悉。
下面上代码,还需要更熟悉一下。

#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
using namespace std;


const int maxn=10010;
int in_order[maxn],post_order[maxn],lef[maxn],righ[maxn];
int n;


bool read_list(int *a){
    string line;
    if(!getline(cin,line))//模板
        return false;
    stringstream ss(line);
    n=0;
    int x;
    while(ss>>x)
    {
        a[n++]=x;
    }
    return true;
}


int build(int l1,int r1,int l2,int r2){
    if(l1>r1)
        return 0;
    int root=post_order[r2];
    int p=l1;
    while(in_order[p]!=root)
        p++;
    int ct=p-l1;
    lef[root]=build(l1,p-1,l2,l2+ct-1);//
    righ[root]=build(p+1,r1,l2+ct,r2-1);
    return root;
}


int best,best_sum;

void dfs(int root,int sum){
    sum+=root;
    if(!lef[root]&&!righ[root]){
        if((sum<best_sum)||(sum==best_sum&&root<best)){
            best=root;
            best_sum=sum;
        }
    }
    if(lef[root]) dfs(lef[root],sum);
    if(righ[root]) dfs(righ[root],sum);
}


int main(void){
    while(read_list(in_order)){
        read_list(post_order);
    best_sum=1000000;
    int op=build(0,n-1,0,n-1);
    dfs(op,0);
    cout<<best<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值