已知前序和中序遍歷求二叉樹
阿新 • • 發佈:2018-12-10
描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請輸出後序遍歷序列。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},重建二叉樹並返回後序遍歷序列
輸入
輸入某二叉樹的前序遍歷和中序遍歷的結果
輸出
輸出後序遍歷序列
輸入樣例 1
1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6
輸出樣例 1
7 4 2 5 8 6 3 1
題意:
前序遍歷即先訪問根節點,然後是左子樹,右子樹
中序遍歷為先訪問左子樹,然後是根節點,右子樹
所以通過前序遍歷不斷地找到根節點,然後中序遍歷找到其左子樹和右子樹
最後就可以得到這棵二叉樹,後序遍歷即為 7 4 2 5 8 6 3 1
實現程式碼:
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node* BinTree; struct node{ int date; BinTree left; BinTree right; }; BinTree Build(int pre[] ,int in[] ,int size) { if(size<=0)return NULL; //先在中序中找到根節點 int i; for(i=0;i<size;i++) { if(in[i]==pre[0])break; } BinTree tree=(BinTree)malloc(sizeof(struct node)); tree->date=pre[0]; tree->left=Build(pre+1,in,i); tree->right=Build(pre+i+1,in+i+1,size-1-i); return tree; } void postorder(BinTree T) //後序遍歷 { if(T==NULL)return; else{ postorder(T->left); postorder(T->right); printf("%d ",T->date); } } int main() { char pree[800],inn[800]; gets(pree); gets(inn); int size=strlen(pree); int pre[800],in[800]; int precount=0; int i; for(i=0;i<size;i++) { if(i==0) { pre[precount]=pree[i]-'0'; } else { if(pree[i]>='0'&&pree[i]<='9') { //此if-else 用來轉換多位數為int型別 if(pree[i-1]==' ') //如果前一個元素為空格 { precount++; pre[precount]=pree[i]-'0'; } else //如果前一個元素不是空格,那麼說明與前一個元素一同構成的數 例如:10 { pre[precount]=pre[precount]*10+(pree[i]-'0'); } } } } int incount=0; for(i=0;i<size;i++) { if(i==0) { in[incount]=inn[i]-'0'; } else { if(inn[i]>='0'&&inn[i]<='9') { if(inn[i-1]==' ') { incount++; in[incount]=inn[i]-'0'; } else { in[incount]=in[incount]*10+(inn[i]-'0'); } } } } //如果前序遍歷的結點數與中序遍歷的結點數相同且不為0,那麼可以找到對應二叉樹 if(precount==incount&&precount!=0) { BinTree T; T=Build(pre,in,precount+1); postorder(T); } return 0; }