用数组实现,由中序、后序遍历构造二叉树,并求最小路径所在的叶子结点
#include<stdio.h> #include<string.h> int left[120];//left[i]=j,表示结点i的左结点是j;i和j均是用vaule标识 int right[120]; //int root; int Inorder[120];//存储先序后序遍历的数组 int Postorder[120]; int ans;//暂存最小路径值 //int sum=0; int flag;//最小路径结点 int Build(int L1,int R1,int L2,int R2){ // printf("$$\n"); if(L1>R1) return 0;//递归终止条件 int p=L1; for(;Inorder[p]!=Postorder[R2];p++);//从后序遍历得到根节点,基于分治的思想在中序遍历中找到划分的位置 //下面递归构造二叉树 int root=Inorder[p]; // printf("p=%d\n",p); int len=p-L1; left[root]=Build(L1,p-1,L2,L2+len-1); right[root]=Build(p+1,R1,L2+len,R2-1); // printf("root=%d\n",root); return root; } void presee(int root,int sum){ if(root!=0){ sum+=root; if(left[root]==0&&right[root]==0){//当到达一个根结点 if(sum<ans||(sum==ans&&root<flag)){ ans=sum; flag=root; } // return 0; } if(left[root]!=0) presee(left[root],sum); if(right[root]!=0) presee(right[root],sum); } } int main(){ char s1[120]; char s2[120]; while(gets(s1)!=NULL){ gets(s2); int cnt1=0,cnt2=0,num=0; memset(left,0,sizeof(left)); memset(right,0,sizeof(right)); memset(Inorder,0,sizeof(Inorder)); memset(Postorder,0,sizeof(Postorder)); ans=10000; // sum=0; flag=10000; //数据处理:字符转化为数字数组 for(int i=0;i<strlen(s1);i++){ if(s1[i]>='0'&&s1[i]<='9'){ num*=10; num+=s1[i]-'0'; }else{ Inorder[cnt1++]=num; num=0; } } Inorder[cnt1]=num;//最后一个 //数据处理:字符转化为数字数组 num=0; for(int i=0;i<strlen(s2);i++){ if(s2[i]>='0'&&s2[i]<='9'){ num*=10; num+=s2[i]-'0'; }else{ Postorder[cnt2++]=num; num=0; } } Postorder[cnt2]=num; //for(int j=0;j<=cnt1;j++) printf("%d--%d\n",Inorder[j],Postorder[j]); int p=0; for(;Inorder[p]!=Postorder[cnt2];p++); //下面递归构造二叉树 /* root=Inorder[p]; left[root]=Build(0,p-1,0,p-1); right[root]=Build(p+1,cnt1,p,cnt2-1);*/ int root=Build(0,cnt1,0,cnt2); //先序遍历; presee(root,0); printf("%d\n",flag); } return 0; }
题目链接:http://dengdengoj.cc/problem.php?id=1113