唔,首先这题给出了中序遍历和后序遍历要求我们求出,
一个叶子节点到根的数值总和最小,且这个叶子节点是最小的那个
这题的难点在于如何运用中序遍历和后序遍历还原整棵树,
这里有两个方法:
1. 递归构造原树。
1. 运用链表构造一棵树。
我将要运用的是链表构造树。
#include<bits/stdc++.h> using namespace std; struct Node{ int v; Node *left,*right; };//首先利用结构体构造树的节点 Node *root;//申请根节点 Node *newnode() {return new Node();}//添加新的节点 const int inf=0x7fffffff;//设定值最大 const int maxn=10000+10; int p[maxn],i[maxn],n,ok,b,best; bool read(int *a)//读入数据,进行存储 { string s; if(!getline(cin,s)) return false;//输入进树的节点数 stringstream tf(s); int x;n=0; while(tf>>x) a[n++]=x; return n>0; } Node* bulid(int l1,int r1,int l2,int r2)//构造树的节点 { if(l1>r1) return NULL;//null==空,所以空数返回空 Node *t=newnode();//申请节点 t->v=p[r2];//运用链表 int p=l1; while(i[p]!=t->v) p++;//添加子树 int cnt=p-l1; t->left=bulid(l1,p-1,l2,l2+cnt-1); t->right=bulid(p+1,r1,l2+cnt,r2-1);//构造左右子树 return t; } void dfs(Node *t,int sum)//用深搜寻找最小值的终端叶子 { sum+=t->v; if(!t->left&&!t->right){//检寻左右子树 if(sum<b||(sum==b&&t->v<best)){ b=sum;best=t->v; } } if(t->left) dfs(t->left,sum); if(t->right) dfs(t->right,sum);//搜索回溯 } int main() { while(read(i)){//输入 read(p); b=inf;best=inf; root=bulid(0,n-1,0,n-1); dfs(root,0);//从根节点开始搜 printf("%d\n",best); } }
就是这个样子啦!!!