二叉樹的恢復

2021-05-31 23:34:59 字數 2382 閱讀 7853

最近筆面老碰上這類題,老忘,因此寫個備忘。

二叉樹的三種遍歷常用於恢復:先序,中序,後序。對於先+中,後+中這兩種組合,對任意二叉樹的恢復都有唯一解,但對先+後的情況則不是,這種情況下要滿足要求:對所有非葉節點,其兩個子節點都存在,也即,乙個節點要麼是葉節點,要麼有兩個節點。

典型的恢復方法是遞迴建構節點的左,右子樹。乙個乙個看:

假設二叉樹原型如下,為了方便,節點的值剛好等於層次遍歷索引

先序:1,2,4,5,10,11,3,6,7,

中序:4,2,10,5,11,1,6,3,7,

後序:4,10,11,5,2,6,7,3,1,

先+中恢復:

對先序,注意第乙個節點是根節點,其遍歷順序是中左右,因此,若把第乙個節點作為基準,則其左右子樹連續儲存在該節點之後,不過,目前我們還不知道到底左右子樹的分界點在哪,因此需要結合中序來確定其分界點。先序的第乙個節點在中序的第5個位置(從0開始算),而我們知道中序的儲存順序是:先中後,因此,對中序列,該節點的左邊是其左子樹,右邊是右子樹。因此,根據節點在中序中的位置可以確定其左子樹的元素個數,對應到先序即可得到該節點的左,右子樹分別在先,中序的位置。根據上述資訊就可遞迴的恢復根節點的左,右子樹,進而得到整個樹。

後+中:

與上述類似,只不對後序,根節點在末尾,其它的可依此類推。

先+後:

這種情況下恢復的二叉樹不一定有唯一解,考慮如下的樹:

先序:1,2

後序:2,1

與先序: 1,2

後序:2,1

可看到不同的樹,先,後序遍歷是一樣的。

其唯一解的條件文章開頭已經說過了。不過沒有經過嚴格考究!

這裡只針對有唯一解的情況做討論,還考慮上圖的例子,結合例項描述如下:

先序:1,2,4,5,10,11,3,6,7,

後序:4,10,11,5,2,6,7,3,1,

對先序,第乙個節點與後序最後節點對應,然後再看先序的第二個節點(值為2),我們知道,如果先序存在子樹,則必同時存在左右子樹,因此可斷定,第二個節點正是根節點的左子樹節點,可先恢復成:

2而它又把後序分成兩個部分,一左一右(右邊不包括最末的根節點):左(4,10,11,5,2),右(6,7,3),說到這裡,再結合上圖,一切都明白了:「左」正是根的左子樹,「右」正是根的右子樹。於是,我們又得到了根節點的左右子樹,遞迴,搞定。

上**:

typedef struct tagtree

tree;

templatevoid show(t* vec,int n)

else

if ( rightidx > a[n-1] || arr[rightidx-1] == 0 )

else

}*node = arrtree;

//test

for (int i=1;i<=n;++i)

cout<

if (arrtree[i-1].right)

cout<

if (arrtree[i-1].parent)

cout

if ( ptree->left )

preorder(ptree->left,out);

if ( ptree->right )

preorder(ptree->right,out);

}void inorder(tree* ptree,int** out)

void postorder(tree* ptree,int** out)

//先+中恢復二叉樹

tree* pre_in(const int* pre,const int* in, int n)

//後+中恢復二叉樹

tree* post_in(const int* post,const int* in, int n)

//先+後恢復二叉樹

tree* pre_post(const int* pre,const int* post, int n)

int _tmain(int argc,char* argv);

//先+後有唯一解的二叉樹,用於測試pre_post函式

const int n = 9;

int a[n] = ;

createtree(&ptree,a,n);

int pre[n];

int in[n];

int post[n];

int* pre_ptr = (int*)pre;

int* in_ptr = (int*)in;

int* post_ptr = (int*)post;

preorder(ptree,&pre_ptr);

inorder(ptree,&in_ptr);

postorder(ptree,&post_ptr);

cout<

二叉樹3(恢復二叉樹)

給一顆帶權 權值各不相同,都是小於10000的正整數 的二叉樹的中序和後序遍歷序列,找乙個葉子使得它到根的路徑上的權值盡可能小,如果有多解,取葉子權值小的。輸入中第一行為中序遍歷,第二行為後序遍歷。例如輸入 3 2 1 4 5 7 6 3 1 2 5 6 7 4 輸出輸入 7 8 11 3 5 16...

恢復二叉搜尋樹 二叉樹

給你二叉搜尋樹的根節點 root 該樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。高階 使用 o n 空間複雜度的解法很容易實現。你能想出乙個只使用常數空間的解決方案嗎?示例 1 輸入 root 1,3,null,null,2 輸出 3,1,null,null,2 解釋 3 不能...

演算法 二叉樹的恢復

3 根據中序和後序遍歷結果恢復二叉樹 二叉樹是乙個極為重要的資料結構,對它的掌握程度反映了反映了我們資料結構的掌握程度,尤其是一些大公司在面試非科班出身的程式設計師的時候就會出一些類似於二叉樹恢復的題目來試探我們。先來看一下這棵二叉樹,我們以他為例 1 2 3 4 5 6 7再看一下遍歷規則 前序遍...