題意:根據前序和中序寫出后序 前序:1 2 4 7 3 5 8 9 6 中序:4 7 2 1 8 5 9 3 6 求出后序:7 4 2 8 9 5 6 3 1
首先得知道是如何前序遍歷、中序遍歷、后序遍歷的,自己上網查下,我在這里就不多說了
思路:第一步:根據前序可知根節點為1;第二步:根據中序可知4 7 2為根節點1的左子樹和8 5 9 3 6為根節點1的右子樹;第三步:遞歸實現,把4 7 2當做新的一棵樹和8 5 9 3 6也當做新的一棵樹;第四步:在遞歸的過程中輸出后序。
代碼實現:
//根據前序和中序遍歷寫出后序遍歷 #include<iostream> using namespace std; int t1[1001],t2[1001]; void sousuo(int a,int b,int n,int flag) { if(n==1)//如果存在左子樹或右子樹就直接輸出 { printf("%d ",t1[a]); return ; } else if(n<=0)//如果不存在左子樹或右子樹就返回上一層 return ; int i;//繼續罰分為左子樹和右子樹 for(i=0;t1[a]!=t2[b+i];i++) ;//找到罰分點也就是根節點 sousuo(a+1,b,i,0);//左子樹的遍歷 sousuo(a+i+1,b+i+1,n-i-1,0);//右子樹的遍歷 if(flag==1)//最原始的跟節點 printf("%d",t1[a]); else//一般的根節點 printf("%d ",t1[a]); } int main() { int n,i; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&t1[i]);//t1中存的是前序 for(i=1;i<=n;i++)//t2中存的中序 scanf("%d",&t2[i]); sousuo(1,1,n,1); printf("\n"); } return 0; }
這是根據前序和中序寫出后序,我現在把題意變成根據后序和中序寫出前序 后序:7 4 2 8 9 5 6 3 1 中序:4 7 2 1 8 5 9 3 6 求出前序:1 2 4 7 3 5 8 9 6
代碼實現:
//根據后序和中序遍歷寫出前序 #include<iostream> using namespace std; int t1[1001],t2[1001]; void sousuo(int a,int b,int n,int flag) { int i; if(n==1)//存在左子樹或右子樹,進行遍歷即可 { printf(" %d",t1[a]); return ; } else if(n<=0)//不存在左子樹或者右子樹,則返回上一層 return ; if(flag==1)//最原始的根節點 printf("%d",t1[a]); else //一般的根節點 printf(" %d",t1[a]); for(i=0;t1[a]!=t2[b+i];i++) ;//找出根節點 sousuo(a-n+i,b,i,0);//左子樹的遍歷 sousuo(a-1,b+i+1,n-i-1,0);//右子樹的遍歷 } int main() { int n,i; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&t1[i]);//t1中存的是后序 for(i=1;i<=n;i++) scanf("%d",&t2[i]);//t2中存的是中序 sousuo(n,1,n,1);//因為后序最后遍歷的是根節點,所以這里和前面的開始點不同,注意一下 printf("\n"); } return 0; }