在樹相關的資料結構中經常利用遞迴思想,這是因為本身樹的定義就是利用遞迴構成的。
舉個例子:樹的每乙個子樹又是一棵樹,那麼你前序遍歷一棵樹,就要從最小的子樹開始,也就是說每乙個子樹的節點在序列中的相對位置,都是滿足前序遍歷的。
那麼我們就可以利用遞迴來進行重建二叉樹。
擁有的條件:1.二叉樹前序序列。 2.二叉樹的中序遍歷。3.序列的長度。
(1)根據前序序列,可以確定根節點數值,利用根節點數值和中序序列可以確定中序序列根節點的位置。
(2)中序序列根節點的左邊為左子樹,右邊為右子樹,進而可以確定,左子樹的個數,右子樹的個數,中序序列中左右子樹的範圍位置。
(3)前序序列中緊挨著根節點(前序序列的第乙個位置)的就是左子樹,根據上面得到的左子樹的個數,可以確定前序序列中左右子樹的範圍位置。
根據(1)(2)(3)是不是又得到了左子樹的前序,中序序列,以及序列的長度,也就是左子樹的1,2,3. 同理還有右子樹的1,2,3.
同理也就可以得到任意小子樹的前序中序序列,而每乙個節點的左右子樹的根節點就是其左右子樹的前序序列的第乙個節點。
那我們就只需做兩件事:將輸入前序序列的第乙個節點儲存為根節點。
根據當前序列,分出左右子樹的前序中序序列,遞迴這兩件事。
binarytreeroot_ptr rebulit_binarytree
(int
*start_preorder,
int*end_preorder,
int*start_inorder,
int* end_inorder)}if
(lchild_length >0)
if((start_inorder + lchild_length)
< end_inorder)
return root;
//非葉子結點,賦值完左右子樹,返回
}
輸入四個量:分別是前序序列的第乙個元素位址,最後乙個元素位址
中序序列的第乙個元素位址,最後乙個元素位址。
新建乙個根節點指標,用於指向根節點。將前序序列的第乙個元素值儲存到根節點。左右子樹位址預設為空。
確定左右子樹的前序和中序的範圍:只要判斷出左子樹的長度,就可以確定左右子樹的前/中序序列。
lchild_length儲存根節點在中序的位置與中序第乙個節點的差值(也就是左子樹的長度):
舉例:前序序列:pre = 中序序列:in =
可知1為根節點,根據中序序列可知4和1的差值為3,也就是lchild_length=3.
那麼前序序列中緊挨1的3個元素為左子樹的前序,後面為右子樹的前序。
中序序列中1的左邊為左子樹的中序,右面為右子樹的中序。
#include
#include
typedef
struct binarytreenode binarytreenode,
*binarytreeroot_ptr;
binarytreeroot_ptr rebulit_binarytree
(int
*start_preorder,
int*end_preorder,
int*start_inorder,
int* end_inorder)
;int
find_location
(int n,
int*a)
;void
display_preorder
(binarytreeroot_ptr root)
;void
display_inorder
(binarytreeroot_ptr root)
;void
display_postorder
(binarytreeroot_ptr root)
;binarytreeroot_ptr construct
(int
*pre,
int*in,
int length)
;void
main()
, in=
, length;
length =
sizeof
(pre)
/sizeof
(int);
struct binarytreenode* root;
root =
(struct binarytreenode *
)malloc
(sizeof
(struct binarytreenode));
root =
construct
(pre, in, length)
;display_preorder
(root)
;printf
("\n");
display_inorder
(root)
;printf
("\n");
display_postorder
(root);}
binarytreeroot_ptr construct
(int
*pre,
int*in,
int length)
return
(binarytreeroot_ptr)
rebulit_binarytree
(pre, pre + length -
1, in, in + length -1)
;}binarytreeroot_ptr rebulit_binarytree
(int
*start_preorder,
int*end_preorder,
int*start_inorder,
int* end_inorder)}if
(root_location >0)
if((start_inorder + root_location)
< end_inorder)
return root;
//非葉子結點,賦值完左右子樹,返回
07 二叉樹 根據前序和中序遍歷重建二叉樹
問題 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。分析 1 先根據前序遍歷的第乙個節點root找到分界點i 2 將前序遍歷陣列和中序遍歷陣列按照分界點進行劃分 3 遞迴 實現 public treenode buildtree int...
重建二叉樹 根據前序遍歷和中序遍歷構建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。思路 1.前序遍歷的第乙個節點一定是根結點。前序遍歷的乙個節點要麼是相鄰前乙個節點的左子樹 右子樹或者更靠近前面節點的右子樹。如何確...
重建二叉樹,根據前序中序遍歷構建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。前序遍歷 根左右 中序遍歷 左根右 根據前序遍歷我們可以知道根節點,根據中序遍歷我們可以知道根節點的左右子樹結點有哪些。如 前序 中...