我們考慮一種簡單的情況,現在假定有這樣一顆二叉樹:
顯然其前序遍歷和中序遍歷分別為
int
preorder =
;int
midorder =
;
我們可以再根據前序遍歷和中序遍歷還原這個二叉樹,其原理為:
前序遍歷總是按照根節點-左子樹-右子樹的順序遍歷,中序遍歷總是按照左子樹-根節點-右子樹的順序遍歷,因此在初始狀態下,preorder[0]中儲存的就是整棵樹的根節點的值。
我們設計乙個pos函式用於找到數字a在指定陣列array中的位置:
public
static
intpos
(int a,
int[
] array)
system.out.
println
(a +
" not found!");
return-1
;}
顯然,對於中序遍歷來說,位於 pos(preorder[0],midorder) 左側的都是這個根節點的左子樹,位於 pos(preorder[0],midorder) 右側的都是這個根節點的右子樹。
我們令 root_pos_at_midorder =
pos(preorder[0]
,midorder)
假定我們在搜尋整棵樹的根節點時,指定的搜尋範圍為
陣列名起始位置
終止位置
現在讓我們把目光轉向根節點的子樹:
在左子樹中,我們同樣要從preorder和midorder陣列獲取這個左子樹自身的根節點、左子樹和右子樹資訊,獲取方法與前面類似,但我們的搜尋範圍有所變化:
那麼當搜尋它的左子樹時,範圍應該為:
陣列名起始位置
終止位置
類似地,搜尋它的右子樹時,範圍應該為:
陣列名起始位置
終止位置
顯然,我們可以定義乙個rebuild方法,指定當前的根節點和兩個陣列的起止位置,遞迴呼叫就能將二叉樹重構出來
package com.ds.bintree;
class
treenode
public string tostring()
}public
class
rebuildbintree
;static
int[
] midorder =
;/**
* 找到數字a在陣列array中的位置
* @param a 數字
* @param array 陣列
* @return
*/public
static
intpos
(int a,
int[
] array)
system.out.
println
(a +
" not found!");
return-1
;}/** * 重建二叉樹
* @param root 根節點
* @param preost 先序遍歷陣列的起始位置
* @param preoed 先序遍歷陣列的終止位置
* @param midost 中序遍歷陣列的起始位置
* @param midoed 中序遍歷陣列的終止位置
*/public
static
void
rebuild
(treenode root,
int preost,
int preoed,
int midost,
int midoed)
//表示右子樹存在
if(midoed - root_pos_at_midorder >0)
}public
static
void
main
(string[
] args)
}
利用前序遍歷和中序遍歷構造二叉樹
根據一棵樹的前序遍歷與中序遍歷構造二叉樹。注意 你可以假設樹中沒有重複的元素。例如,給出 前序遍歷 preorder 3,9,20,15,7 中序遍歷 inorder 9,3,15,20,7 返回如下的二叉樹 3 920 157 思想 利用分治的思想來解決該題 具體解題步驟 1.根據先序遍歷,我們可...
二叉樹 前序遍歷 中序遍歷和後序遍歷
定義 樹是由結點或頂點和邊組成的 可能是非線性的 且不存在著任何環的一種資料結構。沒有結點的樹稱為空 null或empty 樹。一棵非空的樹包括乙個根結點,還 很可能 有多個附加結點,所有結點構成乙個多級分層結構。特點 樹狀圖是一種資料結構,它是由n n 0 個有限結點組成乙個具有層次關係的集合。把...
二叉樹 前序遍歷 中序遍歷 後序遍歷
前序遍歷 dlr 是二叉樹遍歷的一種,也叫做先跟遍歷,先序遍歷,前序周遊,可記做根左右。前序遍歷首先訪問根節點然後遍歷左子樹,最後遍歷右子樹。前序遍歷首先訪問根節點然後遍歷左子樹,最後遍歷右子樹。在遍歷左 右子樹時,仍然先訪問根節點,然後遍歷左子樹,最後遍歷右子樹。若二叉樹為空則結束返回,否則 1 ...