lrn 後序遍歷
通過遍歷序列構造二叉樹
滿二叉樹的前序序列轉後序序列
結點結構:
typedef
struct node
}node;
我們以鏈式儲存的二叉樹為例,二叉樹的遍歷有:
顯然,我們所說的「序」指的是我們對結點進行訪問的先後順序
由兩個函式組成,乙個遞迴函式,以及呼叫這個遞迴函式的函式:
void
preorder()
void
preorder
(node* p)
同理,很簡單我們也可以實現中序遍歷:
void
inorder()
void
inorder
(node* p)
表示式二叉樹
中序遍歷可以用於表示式二叉樹輸出中綴表示式:
void
inorder
(node* p)
// print left ear
std::cout <<
"(";
inorder
(p->left)
;// print value
std::cout << p-
>value;
inorder
(p->right)
; std::cout <<
")";
return
;}
我們不需要考慮運算子優先順序,因為結點層次已經將運算優先順序決定好了,乙個分支結點就是一次運算,因此我們需要在每個分支結點的運算開始前和結束之後列印左右括號,當然根結點則不需要,因此我們可以在呼叫的時候直接傳入根結點的左右後繼:
if
(this
->root !=
null
)
**如下:
void
postorder()
void
postorder
(node* p)
後序遍歷的一些應用:
可以通過:
唯一確定一棵二叉樹。根據遍歷的方式,我們都可以在這三個序列中特定出一些結點,然後通過特定出來的結點將序列劃分出子串行(通常是左子樹和右子樹)。顯然,我們對劃分出來的序列可以進行同樣的操作。也就是這樣,我們可以不斷找出結點的左子樹和右子樹,最後得到整棵二叉樹的結構。
中序 + 後序
首先,對於乙個後序序列,根據後序遍歷的遍歷順序我們可以知道:這個序列的最後乙個結點就是樹的根結點;而對於中序序列來說,如果我們找到它的根結點,那麼,我們可以將這個序列分成兩部分:左子樹的中序序列和右子樹的中序序列。這樣,我們反過來又可以根據左子樹的結點數量在後序序列中找到相應的左子樹的後序序列,同理也可以找到右子樹的後序序列。這樣方法就很明顯了,我們只需要不斷進行這樣的操作,最終可以找到每乙個結點的位置,特定出二叉樹的結構。這也是為什麼必須要有中序序列才能確定二叉樹的結構,因為只有中序序列可以得到左右子樹的結點數量。
也就是說,後序序列總能看成左子樹的前序序列+右子樹的前序序列+根結點,而中序序列可以看成左子樹的前序序列+根結點+右子樹的前序序列,然後不斷確定根結點,左子樹和右子樹,最後特定出二叉樹的結構:
void
postinbuildtree
(elementtype* post,
int postlen, elementtype* in,
int inlen)
// only has one node
else
if(postlen ==1)
// build tree
this
->root =
postinrecsv
(post, postlen, in, inlen);}
node*
postinrecsv
(elementtype* post,
int postlen, elementtype* in,
int inlen)
node* currentroot =
newnode
(post[postlen -1]
);int i =0;
// find root of current tree
for(
;i < inlen;i++)}
// determine left
currentroot-
>left =
postinrecsv
(post, i, in, i)
;// determine right
currentroot-
>right =
postinrecsv
(post + i, inlen - i -
1, in + i +
1, inlen - i -1)
;return currentroot;
}
中序 + 前序
同理,和後序一樣,前序也可以看成:根結點+左子樹的前序序列+右子樹的前序序列,我們採用同樣的方法,最後特定出二叉樹的結構:
void
preinbuildtree
(elementtype* pre,
int prelen, elementtype* in,
int inlen)
// only has one node
else
if(prelen ==1)
// build tree
this
->root =
preinrecsv
(pre, prelen, in, inlen);}
node*
preinrecsv
(elementtype* pre,
int prelen, elementtype* in,
int inlen)
node* currentroot =
newnode
(pre[0]
);int i =0;
// find root of current tree
for(
;i < inlen;i++)}
// determine left
currentroot-
>left =
preinrecsv
(pre +
1, i, in, i)
;// determine right
currentroot-
>right =
preinrecsv
(pre + i +
1, inlen - i -
1, in + i +
1, inlen - i -1)
;return currentroot;
}
對於滿二叉樹來說,任意一種遍歷序列都可以唯一確定這一棵滿二叉樹,因為我們知道每一層的結點數量,以及左右子樹的結點數量(而且是相等的),所以三種序列之間可以互相轉換,思想類似,這裡簡單的介紹一下前序和後序的轉換,首先我們知道,對任意一棵子樹都有:
則僅針對當前的根結點及其左右後繼,只需要把當前根結點放到最前面,就完成了前序到後序的轉換。這樣,我們只需要對每一棵子樹都進行這樣的操作,最終就完成了前序到後序的轉換:
void
pretopost
(elementtype* pre, elementtype post,
int length)
// length for both of the left and right
length = length /2;
// repeat the same operation for children
// for left
pretopost
(pre +
1, post, length)
;// for right
pretopost
(pre + length +
1, post + length, length)
;return
;}
構建二叉樹 遍歷二叉樹
陣列法構建二叉樹 public class main public static void main string args 用陣列的方式構建二叉樹 public static void createbintree 把linkedlist集合轉成二叉樹的形式 for int j 0 j 最後乙個父節...
二叉樹遍歷序列還原
給出二叉樹的中序遍歷序列和後序遍歷序列,程式設計還原該二叉樹。輸入 第1行為二叉樹的中序遍歷序列 第2行為二叉樹的後序遍歷序列 輸出 二叉樹的按層遍歷序列 測試輸入 badcfeg bdfgeca 測試輸出 abcdefg 源 include include include includetyped...
二叉樹建立以及遍歷
題目描述 編乙個程式,讀入使用者輸入的一串先序遍歷字串,根據此字串建立乙個二叉樹 以指標方式儲存 例如如下的先序遍歷字串 abc de g f 其中 表示的是空格,空格字元代表空樹。建立起此二叉樹以後,再對二叉樹進行中序遍歷,輸出遍歷結果。輸入描述 輸入包括1行字串,長度不超過100。輸出描述 可能...