二叉樹的中序後序排列求先序/先序中序排列求後序
阿新 • • 發佈:2019-01-25
7-8 根據後序和中序遍歷輸出先序遍歷 (25 分)
本題要求根據給定的一棵二叉樹的後序遍歷和中序遍歷結果,輸出該樹的先序遍歷結果。
輸入格式:
第一行給出正整數N(≤30),是樹中結點的個數。隨後兩行,每行給出N個整數,分別對應後序遍歷和中序遍歷結果,數字間以空格分隔。題目保證輸入正確對應一棵二叉樹。
輸出格式:
在一行中輸出Preorder:
以及該樹的先序遍歷結果。數字間有1個空格,行末不得有多餘空格。
輸入樣例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
輸出樣例:
Preorder: 4 1 3 2 6 5 7
基本思路就是利用後序排列可以不斷找出根節點,從而在中序排列中找到該節點的位置,將中序排列拆分為左右兩個子樹成為新的中序排列,根據拆分結果可以將後序排列相同拆分為兩個新的後序排列......如此遞迴求解直到子樹為空。在這個遞迴過程中就可以不斷按順序找出各個根節點完成樹的重建!
#include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node *l,*r; }*bt; //根據輸入的中序後序排列來重建樹 bt createTree(int *in,int *post,int n){ //指標in和post指向中後序的起始位置,n是長度 if(n<=0) return NULL; //遞迴出口,返回空指標 int *p=in; //p是從中序排列中找到根的位置 while(p){ if(*p==*(post+n-1)) break; p++; } int len=p-in; //計算長度 bt t=(bt)malloc(sizeof(struct node)); //建立這個節點並賦值,遞迴建立其左右孩子 t->data=*p; t->l=createTree(in,post,len); t->r=createTree(p+1,post+len,n-len-1); //原來長度為n,減去左邊子樹的一段和根節點,長度變為n-len-1 return t; } void preorder(bt t){ //先序遍歷建立的樹得到先序排列 if(t){ printf(" %d",t->data); preorder(t->l); preorder(t->r); } } int main(){ int n,in[50],post[50]; bt t; scanf("%d",&n); for(int i = 0;i < n;i++) scanf("%d",&post[i]); for(int i = 0;i < n;i++) scanf("%d",&in[i]); t=createTree(in,post,n); printf("Preorder:"); preorder(t); return 0; }
同理按照此思路也可以完成已知先序中序求解後序排列,只需要對重建樹的程式碼進行更改:
bt createTree(int *in,int *pre,int n){ if(n<=0) return NULL; int *p=in; while(p){ if(*p==*pre) break; p++; } int len=p-in; bt t=(bt)malloc(sizeof(struct node)); t->data=*p; t->l=createTree(in,pre+1,len); //注意選取位置的變化 t->r=createTree(p+1,pre+1+len,n-len-1); }