如題,已知先序中序/後序中序建立一棵二叉樹。
我們手工建樹的時候,比如一個例子:先序序列:ADECFG,中序序列:DBEAFCG。首先我們都會從先序序列中找到第一個元素A,該元素也就是這個樹的根。然後再在中序序列中找到一樣的元素A,,這樣會將中序序列分成兩個子序列(DBE) (FCG),分別是左子樹與右子樹。然後將子序列再看成一棵樹。顯然這是一個遞歸的過程。所以只需要把首層的搞清楚。
- 算法思想:兩個數組a[], b[], 分別是樹的先序序列和中序序列。p1,q1代表a[]的首尾;p2,q2代表b[的首尾。首先先取a[p1]的值(也就是例子中的A),其次在b[]中找到該值,並返回下標。定義llen(左子樹長度),rlen(右子樹長度)。求出分得的子序列長度執行遞歸即可。//函數參數列表 CreateLBTree1(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2)
- 算法C++描述
//先序中序確定樹 void CreateLBTree1(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2) { int llen, rlen; lbt = (LBTree*)malloc(sizeof(LBTree)); lbt->data = a[p1]; int i; for (i = p2; b[i] != lbt->data; ++i); llen = i - p2; rlen = q2 - i; if (llen) CreateLBTree1(lbt->lchild, a, b, p1 + 1, p1 + llen, p2, p2 + llen - 1); else lbt->lchild = NULL; if (rlen) CreateLBTree1(lbt->rchild, a, b, q1 - rlen + 1, q1, q2 - rlen + 1, q2); else lbt->rchild = NULL; }
-
後序中序建樹的過程與之相似這裏只提供代碼:
//後序中序確定樹 void CreateLBTree2(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2) { int llen, rlen; lbt = (LBTree*)malloc(sizeof(LBTree)); lbt->data = a[q1]; int i; for (i = p2; b[i] != lbt->data; ++i); llen = i - p2; rlen = q2 - i; if (llen) CreateLBTree2(lbt->lchild, a, b, p1, p1 + llen - 1, p2, p2 + llen - 1); else lbt->lchild = NULL; if (rlen) CreateLBTree2(lbt->rchild, a, b, q1 - rlen, q1 - 1, q2 - rlen + 1, q2); else lbt->rchild = NULL; }
該算法的關鍵就是在調用遞歸函數時的參數的賦值。也就是子序列首尾的值。