uva548题解--tree题解

题干

UVA548 树 Tree
题目描述

输入一个二叉树的中序和后序遍历,请你输出一个叶子节点,该叶子节点到根的数值总和最小,且这个叶子是编号最小的那个。 输入: 您的程序将从输入文件中读取两行(直到文件结尾)。第一行是树的中序遍历值序列,第二行是树的后序遍历值序列。所有值将不同,大于零且小于或等于10000.二叉树的节1<=N<=10000。 输出: 对于每个树描述,您应该输出最小值路径的叶节点的值。存在多路径最小的情况下,您应该选择终端叶子节点上具有最小值的那条路径,且输出那个最小值的终端叶子。
输入格式
若干行,每两行分别是中序式和后序式
输出格式
输出最小路径的最小叶子
输入

3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255

输出

1
3
255

思路

首先需要知道如何通过中序和后序得到树,我们通过后序的最后一个数即为根,然后再在中序里面找到根,根左右的数串即为左右子树。
由此我们的函数参数设置为树节点和中序后序的两端,然后让树节点等于根的值,然后递归左右子树,直到传入的数串只有一个数就return
接着寻找最小路径,只需按照前序遍历(BFS)深度遍历,记录路径的最小值即可。
注意全局变量的管理

bug修复过程

每次叶子输出为零,我们改变叶子的初值为6,输出6,也就是叶子改变的逻辑没变。
试着输出树,未遂,故初步考虑createtree或bfs或main读取函数或者main里面调用两个函数的问题
输出in[]和post[],是正确的,考虑createtree或bfs或调用函数错误
仔细分析,初步排除dfs逻辑问题,初步排除createtree函数递归调用的参数问题
初步排除createtree的逻辑问题
检查函数调用,发现dfs(root,maxsum)有问题,dfs传入的初值应该是sum=0而不是maxsum。脑抽了。
修改,ac

代码

#include<iostream>
#include<cstring>
#include<sstream>
#include<string>
using namespace std;
const int maxn=10010;
struct node{
    int value;
    struct node * lchild;
    struct node * rchild;
    node():value(-1),lchild(NULL),rchild(NULL){}
};
int in[maxn],post[maxn],maxsum,leave;
node *root;
//全局变量 root,in,post,maxsum,leave
void CreateTree(node *TempTree,int StaIn,int EndIn,int StaPo,int EndPo){
    TempTree->value=post[EndPo];
    if(StaPo==EndPo){
        TempTree->lchild=NULL;TempTree->rchild=NULL;
        return ;
    }
    int i;
    for(i=StaIn;i<EndIn+1;i++) if(in[i]==post[EndPo])break;
    if(i==StaIn) TempTree->lchild=NULL;
    else {
        TempTree->lchild=new node;
        CreateTree(TempTree->lchild,StaIn,i-1,StaPo,StaPo+i-1-StaIn);
    }
    if(i==EndIn) TempTree->rchild=NULL;
    else{
        TempTree->rchild=new node;
        CreateTree(TempTree->rchild,i+1,EndIn,StaPo+i-StaIn,EndPo-1);
    }
    return ;
}
void dfs(node *TempTree,int sum){    
    if(TempTree!=NULL)sum+=TempTree->value;
    if(TempTree->lchild==NULL&&TempTree->rchild==NULL){
        if(sum<=maxsum){            
            if(sum==maxsum){
                if(TempTree->value<leave)leave=TempTree->value;
            }
            else {
                maxsum=sum;
                leave=TempTree->value;
            }
        }
        return ;
    }
    if(TempTree->lchild!=NULL)dfs(TempTree->lchild,sum);
    if(TempTree->rchild!=NULL)dfs(TempTree->rchild,sum);
    return ;
}
int main(){
    while(1){
        maxsum=100000000;leave=0;root=new node;
        memset(in,0,maxn);memset(post,0,maxn);
        string a,b;
        getline(cin,a);getline(cin,b);
        if(a.empty())break;
        int num,count=0;
        istringstream issa(a);
        while(issa>>num){in[count++]=num;}
        count=0;
        istringstream issb(b);
        while(issb>>num)post[count++]=num;
        CreateTree(root,0,count-1,0,count-1);
        dfs(root,0);
        cout<<leave<<endl;
    }
}

紫书上面是数组模拟树的方法,大致逻辑应该差不多,有空实现下

posted @ 2025-08-17 17:21  hardestnut  阅读(13)  评论(0)    收藏  举报