說明:
本次實驗利用中序和先序序列,采用遞歸方式來構建二叉樹 。
經過幾天的失敗和思考,我認為遞歸構建二叉樹的過程中最重要的是遞歸單元,最麻煩的是遞歸參數的選擇和傳遞。
簡單將算法過程用如下流程圖來表示:(本帖所用算法及圖片均為原創內容,轉貼注明出處)
算法:1.根據先序序列,建立根結點T
2.尋找中序序列的根結點位置,並據此位置計算左子樹和右子樹的區間
3.判斷l_start和r_end是否相等,相等則表示只有一個根結點,設置其左右孩子結點為空並結束這一層;若不相等則繼續下面步驟:
4.根據2中的左孩子區間,若區間不空,遞歸調用函數自身;若區間為空則令其左孩子為空;
5.根據2中的右孩子區間,若區間不空,遞歸調用函數自身;若區間為空則令其右孩子為空;
代碼實現如下:
1 //6.根據先序和中序序列構建二叉樹 2 typedef int ElemType; 3 typedef int Status; 4 5 typedef struct BTNode{ 6 ElemType data; 7 struct BTNode *lchild,*rchild; 8 }BTree; 9 int Pre[7]={1,2,3,4,5,6,7},In[7]={3,2,4,1,6,5,7}; 10 int preRoot=0; 11 Status CreByPreIn(BTree *root,int l_start,int r_end){ 12 int nowpos=0; 13 root->data=*(Pre+preRoot); 14 while(*(In+nowpos)!=root->data)nowpos++; 15 preRoot++; 16 if(l_start == r_end){ 17 root->lchild=NULL; 18 root->rchild=NULL; 19 return OK; 20 } 21 if(l_start<=nowpos){ 22 BTree *lt=(BTree*)malloc(sizeof(BTree)); 23 root->lchild=lt; 24 CreByPreIn(root->lchild,l_start,nowpos-1); 25 } 26 else root->lchild=NULL; 27 if(nowpos<=r_end){ 28 BTree *rt=(BTree*)malloc(sizeof(BTree)); 29 root->rchild=rt; 30 CreByPreIn(root->rchild,nowpos+1,r_end); 31 } 32 else root->rchild=NULL; 33 }
感想:對於這個算法,最困擾我的就是遞歸的參數傳遞問題,因為是編程之前接觸的少,遞歸也算是第一次自己寫,所以走了很多彎路。
我的收獲就是,編寫程序之前一定要先設計好算法的流程,最好能夠將算法需要用到的參數,變量,函數名都預先寫好,這樣更有利於算法轉化為代碼實現。
理解遞歸,多參考一下別人的經驗吧,帶圖的最好了,不帶圖的都是耍流氓。
歡迎大家和我交流,相互學習。