已知二叉樹的中序和前序序列(或後序)求解樹

在學算法結構時,發現了這個問題,雖然在上數據結構時老師講過,但是隻講過具體例子,沒有讓我們訓練代碼,借這次機會,上網查找了相關資料,而且這學期又剛好在學C++,感覺真的可以好好學一下。。。在網上找的資料,貼在這裏和大家共享

 

這種題一般有二種形式,共同點是都已知中序序列。如果沒有中序序列,是無法唯一確定一棵樹的,證明略。

一、已知二叉樹的前序序列和中序序列,求解樹。

1、確定樹的根節點。樹根是當前樹中所有元素在前序遍歷中最先出現的元素。

2、求解樹的子樹。找出根節點在中序遍歷中的位置,根左邊的所有元素就是左子樹,根右邊的所有元素就是右子樹。若根節點左邊或右邊爲空,則該方向子樹爲空;若根節點左邊和右邊都爲空,則根節點已經爲葉子節點。

3、遞歸求解樹。將左子樹和右子樹分別看成一棵二叉樹,重複1、2、3步,直到所有的節點完成定位。

二、已知二叉樹的後序序列和中序序列,求解樹。

1、確定樹的根。樹根是當前樹中所有元素在後序遍歷中最後出現的元素。

2、求解樹的子樹。找出根節點在中序遍歷中的位置,根左邊的所有元素就是左子樹,根右邊的所有元素就是右子樹。若根節點左邊或右邊爲空,則該方向子樹爲空;若根節點左邊和右邊都爲空,則根節點已經爲葉子節點。

3、遞歸求解樹。將左子樹和右子樹分別看成一棵二叉樹,重複1、2、3步,直到所有的節點完成定位。

舉例說明:根據已知求解二叉樹

中序序列 HLDBEKAFCG
後序序列 LHDKEBFGCA

1、在後序序列LHDKEBFGCA中最後出現的元素爲A,HLDBEK|A|FCG
2、在後序序列LHDKEB中最後出現的元素爲B,HLD|B|EK|A|FCG
3、在後序序列LHD中最後出現的元素爲D,HL|D|B|EK|A|FCG
4、在後序序列LH中最後出現的元素爲H,H|L|D|B|EK|A|FCG
5、在後序序列KE中最後出現的元素爲E,H|L|D|B|E|K|A|FCG

5、在後序序列FGC中最後出現的元素爲C,H|L|D|B|E|K|A|F|C|G
6、所有元素都已經定位,二叉樹求解完成。

A
              /     /
             B       C
            / /     /  /
           D  E     F   G
          /    /
         H      K                    
          /                         
           L                     
代碼如下:
  1 /*
  2     功能: 1.利用樹的前序和中序序列創建樹
  3           2.利用樹的後序和中序序列創建樹
  4 */
  5 #include <iostream>
  6 #include <cstring>
  7 using namespace std;
  8 
  9 char pre[50= "ABDHLEKCFG";        //前序序列
 10 char mid[50= "HLDBEKAFCG";        //中序序列
 11 char post[50= "LHDKEBFGCA";        //後序序列
 12 
 13 typedef struct _Node
 14 {
 15     char v;
 16     struct _Node *left;
 17     struct _Node *right;
 18 }Node, *PNode;
 19 
 20 void PostTravelTree(PNode pn);        //樹的後序遞歸遍歷
 21 void PreTravelTree(PNode pn);        //樹的前序遞歸遍歷
 22 void PreMidCreateTree(PNode &pn, int i, int j, int len);        //利用前序中序序列創建樹
 23 void PostMidCreateTree(PNode &pn, int i, int j, int len);        //利用後序中序序列創建樹
 24 int Position(char c);                //確定c在中序序列mid中的下標,假設樹的各個節點的值各不相同
 25 
 26 
 27 int main() 
 28 
 29     PNode root1 = NULL, root2= NULL;
 30 
 31     PreMidCreateTree(root1, 00, strlen(mid));
 34     PostTravelTree(root1); cout<<endl;    
 36     PostMidCreateTree(root2, strlen(post)-10, strlen(mid));
 37     PreTravelTree(root2); cout<<endl;    
 38 
 39     return 0;
 40 }
 41 
 42 
 43 int Position(char c)
 44 {
 45     return strchr(mid,c)-mid;
 46 }
 47 
 48 
 49 /*  利用前序中序序列創建樹,參考了http://hi.baidu.com/sulipol/blog/item/f01a20011dcce31a738b6524.html
 50  *的實現,代碼十分簡潔,竟然只有短短的"令人髮指"的8行,遞歸實在太彪悍了!!!!!!!!!!!!!!!!!!!!!
 51  *        i: 子樹的前序序列字符串的首字符在pre[]中的下標
 52  *        j: 子樹的中序序列字符串的首字符在mid[]中的下標
 53  *      len: 子樹的字符串序列的長度
 54  */
 55 void PreMidCreateTree(PNode &pn, int i, int j, int len)
 56 {
 57     if(len <= 0)
 58        {   
                  pn = NULL;                 //  這部分原資料裏出了點小問題,原資料裏沒有這一句,結果我在試的時候出了問題
                  return;
              }
 59          
 60     pn = new Node;
 61     pn->= pre[i];
 62     int m = Position(pre[i]);
 63     PreMidCreateTree(pn->left, i+1, j, m-j);            //m-j爲左子樹字符串長度
 64     PreMidCreateTree(pn->right, i+(m-j)+1, m+1, len-1-(m-j));    //len-1-(m-j)爲右子樹字符串長度
 65 }
 66 
 67 
 68 /*  利用後序中序序列創建樹
 69  *        i: 子樹的後序序列字符串的尾字符在post[]中的下標
 70  *        j: 子樹的中序序列字符串的首字符在mid[]中的下標
 71  *      len: 子樹的字符串序列的長度
 72  */
 73 void PostMidCreateTree(PNode &pn, int i, int j, int len)
 74 {
 75     if(len <= 0)
          {
               pn = NULL;
 76         return;
          }
 77 
 78     pn = new Node;
 79     pn->= post[i];
 80     int m = Position(post[i]);
 81     PostMidCreateTree(pn->left, i-1-(len-1-(m-j)), j, m-j);//注意參數:m-j左子樹的長度,len-1-(m-j)右子樹的長度
 82     PostMidCreateTree(pn->right, i-1, m+1, len-1-(m-j));
 83 }
 84 
 85 
 86 void PostTravelTree(PNode pn)        //後序遞歸遍歷
 87 {
 88     if(pn)
 89     {
 90         PostTravelTree(pn->left);    
 91         PostTravelTree(pn->right);
 92         cout<<pn->v<<" ";
 93     }
 94 }
 95 
 96 
 97 void PreTravelTree(PNode pn)        //前序遞歸遍歷
 98 {
 99     if(pn)
100     {
101         cout<<pn->v<<" ";
102         PreTravelTree(pn->left);    
103         PreTravelTree(pn->right);
104     }
105 

參考網站  http://www.cnblogs.com/bmrs/archive/2010/08/19/slovetree.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章