樹的遍歷
給定一棵二叉樹的後序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這裡假設鍵值都是互不相等的正整數。
輸入格式:
輸入第一行給出乙個正整數n(≤30),是二叉樹中結點的個數。第二行給出其後序遍歷序列。第三行給出其中序遍歷序列。數字間以空格分隔。
輸出格式:
在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。
輸入樣例:
72 3 1 5 7 6 4
1 2 3 4 5 6 7
輸出樣例:
4 1 6 3 5 7 2
解題思路:開兩個全域性陣列存放中序/後序遍歷輸入。然後遞迴建樹+層序遍歷
要點:1.遞迴建樹判斷左右子樹是否存在,若存在如何遞迴,若不存在則子結點賦為null
2.層序遍歷借助佇列
建樹**:
treenode*
build
(int inb,
int ine,
int postb,
int poste)
//build
這裡說一下左右子樹的存在判定條件以及左右子樹如何實現遞迴建立:
判定條件:
中序遍歷中,根節點的左邊表示左子樹。如果根節點左邊還有值,說明左子樹存在。i是根節點到中序遍歷第乙個值(最左邊乙個值)的距離,當距離i > 0說明中序遍歷中當前節點的值並不位於最左邊,它的左邊還有值,即左子樹存在。
同理,中序中根節點的右側表示右子樹。若根節點(inb + i)右邊還有值說明右子樹存在。是否還有值通過根節點的索引到最後乙個數的索引之間是否相等來判斷。相等則沒有值,小於則還有值(inb+i遞迴建立:
如何遞迴應該是這題的乙個難點。
建立左子樹:
先考慮中序遍歷的兩個引數 inb 和 ine:每次遞迴取根節點(根節點索引為inb + i)的左半部分,也就是[inb,inb + i -1]
然後後序遍歷的兩個引數postb及poste:每次遞迴取根節點的左子樹部分。那麼後序遍歷中某個特定的根節點左子樹應該怎麼確定呢?實際上,這裡左子樹的元素數跟上面中序的左半部分元素數應該是相等的(因為是同乙個根節點的子節點,二者表述的意義相同只是方式順序不同)並且我們知道,中後序都是先輸出左子樹。也就是說,只要在後序遍歷上截出乙個跟中序左子樹同樣長度的序列(inb+i-1-inb = i-1),就是我們要的部分。這個部分用**描述:[postb,postb + i - 1]
建立右子樹
同樣先考慮中序部分:取根節點的右半部分區間 [inb + i + 1,ine]
然後後序遍歷的兩個引數:由上得,後序遍歷的前半部分是左子樹[postb,postb + i - 1],而我們知道最後乙個元素是根節點(poste)。那麼剩下的部分就是右子樹。即 [postb +i ,poste - 1] (後序遍歷的陣列各個部分在二叉樹中的分布參照下圖:)
可以對比著看看 中序遍歷陣列結構如下
層序遍歷**:
void
levelorder
(treenode* t)
if(front-
>rchild !=
null
)//右結點入隊
q.push
(front-
>rchild);if
(front-
>val != t-
>val)
//輸出
cout<<
" ";
cout<
>val;}}
//levelorder
層序遍歷這裡主要就是借助佇列來完成。詳細可以看看這篇博文:
與上文不同的是,本題要求輸出末尾不可以有空格。所以空格乾脆在每乙個資料之前輸出,然後特判一下第乙個資料(根節點)不輸出即可。
完整的ac**:
#include
using
namespace std;
typedef
struct treenodetreenode;
int inorder[35]
,postor[35]
;//因為函式build需要用到,中序後序應該建成全域性陣列
treenode*
build
(int inb,
int ine,
int postb,
int poste)
//build
void
levelorder
(treenode* t)
if(front-
>rchild !=
null
)//右結點入隊
q.push
(front-
>rchild);if
(front-
>val != t-
>val)
//輸出
cout<<
" ";
cout<
>val;}}
//levelorder
void
deletetree
(treenode * t)
intmain()
建樹部分參考自:
注意不可直接結合兩個博文,應該在第二個連線的基礎上加上這個部分:
if
(i >0)
//左子樹存在
newnode-
>lchild =
build
(inb,inb + i -
1,postb,postb + i -1)
;//中後左子樹長度相等,且位置相同
else
newnode-
>lchild =
null
;//即使是空值也必須初始化!
if(inb + i < ine)
//右子樹存在
newnode-
>rchild =
build
(inb + i +
1,ine,postb + i ,poste -1)
;//注意最後乙個結點是已經賦給樹的根節點,應該刨除
else
newnode-
>rchild =
null
;//同上,否則層序遍歷無法進行
因為第二篇博文使用的層序遍歷稍微複雜一些(使用了vector),好像不需要左右子節點為空的時候置null(這個bug老是段溢位找了我三個點。。。我太難了┭┮﹏┭┮) 已知中序遍歷和後序遍歷,求前序遍歷
已知中序遍歷和後序遍歷,求前序遍歷 演算法的主要部分是將中序遍歷分成左中右三部分 將後序遍歷分成左右中三部分 最後後序建樹的時候節點就等於中間的部分 左子樹由中序遍歷的左部分和後序遍歷的左部分構建 右子樹由中序遍歷的右部分和後序遍歷的右部分構建 include include include inc...
已知後序遍歷和中序遍歷求前序遍歷
而已知後序遍歷和中序遍歷求前序遍歷的過程差不多,但由於後序遍歷是最後才訪問根節點的 所以要從後開始搜尋,例如上面的例子,後序遍歷為 gbdehfca,中序遍歷為 dgbaechf 後序遍歷中的最後乙個元素是根節點,a,然後查詢中序中a的位置 把中序遍歷分成 dgb a echf,而因為節點個數要對應...
(後序 中序建樹)根據後序和中序遍歷輸出先序遍歷
本題要求根據給定的一棵二叉樹的後序遍歷和中序遍歷結果,輸出該樹的先序遍歷結果。第一行給出正整數 n 是樹中結點的個數。隨後兩行,每行給出 n個整數,分別對應後序遍歷和中序遍歷結果,數字間以空格分隔。題目保證輸入正確對應一棵二叉樹。在一行中輸出preorder 以及該樹的先序遍歷結果。數字間有1個空格...