定理:
僅根據先序、中序、后序序列中的其中一個無法唯一確定一個二叉樹。
根據二叉樹的中序序列+前序序列 或者中序序列+后序序列 可以唯一確定一個二叉樹,這里給出了構造方法。

1 #include<cstdio> 2 #include<string.h> 3 #include<malloc.h> 4 using namespace std; 5 #define MaxSize 100 6 typedef char ElemType; 7 typedef struct node 8 { 9 ElemType data; 10 struct node* lchild; 11 struct node* rchild; 12 }BTNode; 13 14 void CreateBTree(BTNode * &b, char * str)//傳入地址b,將其作為根 15 { 16 BTNode *St[MaxSize],*p=NULL; //建立指針型數組? 17 int top=-1,k,j=0;//top為棧頂指針,k為標記,j為字符串指針 18 19 b=NULL;//初始化樹為空 20 char ch=str[j];//j指向字符串的指針 21 while(ch!='\0')//掃描字符串 22 { 23 switch(ch)//判斷當前字符 24 { 25 case '(':St[++top]=p;k=1;break;//接下來的節點為左子樹 26 case ')':--top;break; 27 case ',':k=2;break; 28 default:p=(BTNode *)malloc(sizeof(BTNode));//當前字符為節點 29 p->data=ch;p->lchild=p->rchild=NULL; 30 if(b==NULL) b=p;//第一個節點當做根節點 31 else 32 { 33 switch(k) 34 { 35 case 1:St[top]->lchild=p;break; 36 case 2:St[top]->rchild=p;break; 37 38 } 39 } 40 41 } 42 ch=str[++j]; 43 } 44 } 45 46 void DestroyBTree(BTNode * &b)//銷毀當前二叉樹 47 { 48 if(b!=NULL) 49 { 50 DestroyBTree(b->lchild); 51 DestroyBTree(b->rchild); 52 free(b);//遞歸釋放節點空間 53 } 54 } 55 56 void DispBTree(BTNode *b) 57 { 58 if(b!=NULL) 59 { 60 printf("%c",b->data); 61 if (b->lchild!=NULL || b->rchild!=NULL) 62 { printf("("); 63 DispBTree(b->lchild); //遞歸處理左子樹 64 if (b->rchild!=NULL) printf(","); //有右孩子結點時才輸出',' 65 DispBTree(b->rchild); //遞歸處理右子樹 66 printf(")"); 67 } 68 } 69 }
具體思路為:(分治,遞歸)
1根據先序或者后序序列先找出當前樹的根節點
2然后從中序序列中找到根節點所在的位置
3中序序列中,根節點之前的屬於左子樹,根節點之后的屬於右子樹
4對左子樹和右子樹所在的序列分別進行1~3操作。

1 #include "二叉樹基本操作.cpp" //調用自己的函數庫 2 #define MaxWidth 40 3 /*函數功能: 4 根據前序和中序字符串 創建二叉樹, 5 輸入當前子樹前序中序字符串的首地址 6 以及當前子樹的節點數 7 8 */ 9 BTNode *CreateBT1(char *pre ,char *in,int n) 10 { 11 BTNode *b; 12 char *p;//當前節點指針 13 if(n<=0) return NULL; 14 b=(BTNode *)malloc(sizeof(BTNode)); //創建二叉樹結點*b 15 b->data=*pre;//先序序列的第一個節點即為根節點 16 for(p=in;p<in+n;p++) //在中序序列中尋找根節點的位置 17 if(*p==*pre) break; 18 int k=p-in;//左子樹的節點數 19 b->lchild=CreateBT1(pre+1,in,k); 20 b->rchild=CreateBT1(pre+k+1,p+1,n-k-1); 21 22 return b; 23 } 24 BTNode *CreateBT2(char *post,char *in,int n) 25 { BTNode *b; 26 char r,*p; 27 int k; 28 if (n<=0) return NULL; 29 r=*(post+n-1); //根結點值 30 b=(BTNode *)malloc(sizeof(BTNode)); //創建二叉樹結點*b 31 b->data=r; 32 for (p=in;p<in+n;p++) //在in中查找根結點 33 if (*p==r) break; 34 k=p-in; //k為根結點在in中的下標 35 b->lchild=CreateBT2(post,in,k); //遞歸構造左子樹 36 b->rchild=CreateBT2(post+k,p+1,n-k-1); //遞歸構造右子樹 37 return b; 38 } 39 int main() 40 { 41 BTNode *b; 42 ElemType pre[]="ABDEHJKLMNCFGI"; 43 ElemType in[]="DBJHLKMNEAFCGI"; 44 ElemType post[]="DJLNMKHEBFIGCA"; 45 int n=14; 46 b=CreateBT1(pre,in,n); 47 printf("先序序列:%s\n",pre); 48 printf("中序序列:%s\n",in); 49 printf("構造一棵二叉樹b:\n"); 50 printf(" 括號表示法:");DispBTree(b);printf("\n"); 51 b=CreateBT2(post,in,n); 52 printf("構造一棵二叉樹b:\n"); 53 printf(" 括號表示法:");DispBTree(b);printf("\n"); 54 DestroyBTree(b); 55 return 0; 56 }

#include<stdio.h> #include<malloc.h> #include<cstring> #include<iostream> using namespace std; typedef struct Bnode /* 定義二叉樹存儲結構*/ { char data; struct Bnode *lchild,*rchild;``` } BtNode,*BTree; BtNode *Q[100]; //隊列Q放樹結點地址 BtNode *CreatBTree()//輸入為完全二叉樹的前提下,構建二叉樹 { char ch ,str[20]; int front=1,rear=0;//定義隊列的頭尾指針 int i, n; BtNode *root = NULL, *s; gets(str); n=strlen(str); cout<<n<<endl; for(i=1; i<n; i++) //結束標志 { s=NULL; if (str[i]!='#') //當前字符非空,建立節點加入隊列 { s=(BtNode *)malloc(sizeof(BtNode)); //生成新結點 s->data=str[i]; s->lchild=NULL; s->rchild=NULL; } Q[++rear]=s; //結點入隊 if (rear==1) root=s; //記錄根結點 else { if (s && Q[front]) { if (rear%2==0) Q[front]->lchild=s; //左孩子入隊 else Q[front]->rchild=s; //右孩子入隊 } if (rear%2==1) front++; //新結點是雙親的右孩子,則雙親結點出隊 } } return root; } void preorder(BTree T)//先序遍歷 { if(T) { cout<<T->data<<" "; preorder(T->lchild); preorder(T->rchild); } } void inorder(BTree T)//中序遍歷 { if(T) { inorder(T->lchild); cout<<T->data<<" "; inorder(T->rchild); } } void posorder(BTree T)//后序遍歷 { if(T) { posorder(T->lchild); posorder(T->rchild); cout<<T->data<<" "; } } int main() { BtNode * mytree; mytree=CreatBTree();/*創建二叉樹*/ cout<<"二叉樹的先序遍歷結果:"<<endl; preorder(mytree);//先序遍歷二叉樹 cout<<endl; cout<<"二叉樹的中序遍歷結果:"<<endl; inorder(mytree);//中序遍歷二叉樹 cout<<endl; cout<<"二叉樹的后序遍歷結果:"<<endl; posorder(mytree);//后序遍歷二叉樹 cout<<endl; return 0; }