根據二叉樹的前中序確定唯一的二叉樹
阿新 • • 發佈:2019-02-01
關鍵是怎麼根據前中序推出二叉樹。假設前序為1245367,中序為4251637。那麼根結點為1,在中序中找到1,則左邊為1的左子樹,右邊為1的右子樹。那麼可以根據這個在前序序列中和中序序列中,分出1的左子樹和右子樹在進行按照1的計算方法分別計算,直到找到葉子結點。。可以確定樹。關鍵是利用了樹的遞迴性質。
程式碼實現:先建樹,然後算出其前序和中序序列,最後再根據序列求出樹,看是否和剛開始建的樹相同,程式碼如下:
#include<iostream> #include<string> #include<stack> #include<queue> using namespace std; int porder[10]; int iorder[10]; struct Btree{ int value; Btree* left; Btree* right; }; Btree* Build( ){ int x; Btree* temp; scanf("%d",&x); if(x == 0) temp = NULL; else{ temp = (Btree *)malloc(sizeof(Btree)); temp->value = x; printf("輸入%d結點的左結點\n",x); temp->left = Build(); printf("輸入%d結點的右結點\n",x); temp->right = Build(); } return temp; } //遞迴遍歷 void preorder(Btree* root){ if(root == NULL) return; int i =0; stack<Btree*> Bstack; while(root || !Bstack.empty()){ while(root){ porder[i++] = root->value; Bstack.push(root); root = root->left; } if(!Bstack.empty()){ root = Bstack.top(); Bstack.pop(); root = root->right; } } for(int i =0;porder[i]!= 0;i++) printf("%d",porder[i]); printf("\n"); } //中序遍歷 void inorder(Btree* root){ if(root == NULL) return; int i =0; stack<Btree*> Bstack; while(root || !Bstack.empty()){ while(root){ Bstack.push(root); root = root->left; } if(!Bstack.empty()){ root = Bstack.top(); Bstack.pop(); iorder[i++] = root->value; root = root->right; } } for(int i =0;iorder[i]!= 0;i++) printf("%d",iorder[i]); printf("\n"); } //層次輸出樹 void printTree(Btree* root){ if(root == NULL) return; queue<Btree *> Bq; Bq.push(root); while(!Bq.empty()){ root = Bq.front(); Bq.pop(); printf("%d",root->value); if(root->left) Bq.push(root->left); if(root->right) Bq.push(root->right); } printf("\n"); } //根據前中序構建樹 Btree* prBuild(int pstart,int pend,int istart,int iend){ //空返回即葉子結點的左右子樹 if(pstart>pend || istart>iend) return NULL; Btree* root = (Btree* )malloc(sizeof(Btree)); root->value = porder[pstart]; int i = istart; for(;i<=iend;i++){ if(iorder[i] == porder[pstart]) break; } int leftlen = i-istart; int rightlen= iend-i; //遞迴左子樹 root->left = prBuild(pstart+1,pstart+leftlen,istart,istart+leftlen-1); //遞迴右子樹 root->right= prBuild(pstart+leftlen+1,pend,i+1,iend); return root; } int main(){ Btree *root = Build(); memset(porder,0,sizeof(porder)); memset(iorder,0,sizeof(iorder)); printf("前序遍歷為:\n"); preorder(root); printf("中序遍歷為:\n"); inorder(root); printf("層次遍歷為:\n"); printTree(root); int len =0; for(;porder[len]!=0;len++); Btree* nroot = prBuild(0,len-1,0,len-1); printf("根據前中序層次遍歷為:\n"); printTree(nroot); system("PAUSE"); return 0; }