一、鏈式儲存結構
由於順序儲存二叉樹的空間利用率較低,因此二叉樹一般都採用鏈式儲存結構,用鍊錶結點來儲存二叉樹中的每個結點。在二叉樹中,結點結構通過包括若干資料域和若干指標域,二叉鍊錶至少包含3個域:資料域 data、左指標域 lchild和右指標域 rchild,如下圖所示:
其中,n 個結點的二叉鍊錶中含有 n+1 [ 2n-(n-1)=n+1 ] 個空指標域。
二、線索二叉樹
傳統的二叉鍊錶僅能體現出一種父子關係,不能直接得到結點在遍歷中的前驅或後繼。引入線索二叉樹正是為了加快查詢結點前驅和後繼的速度。
規定:若無左子樹,令 lchild指向其前驅結點;若無右子樹,令rchild執行指向其後繼結點。增加兩個標誌域標識是指向左/右孩子還是指向前驅/後繼。
其標誌位含義如下:
這種加上線索的二叉鍊錶稱為線索鍊錶,相應的二叉樹稱為線索二叉樹。根據線索性質的不同, 線索二叉樹可分為前序線索二叉樹、 中序線索二叉樹和後序線索二叉樹三種。
1.1、中序線索二叉樹
1.1.1 中序線索二叉樹的構造
設定結點pre指向剛剛訪問過的結點,結點node指向正在訪問的結點,即pre指向node的前驅。在遍歷過程中,檢查node的左指標是否為空,若為空就將它指向pre;檢查pre的右指標是否為空,若為空就將它指向node。
public
static
void
inthreadnode
(node node)
//線索化左子樹
inthreadnode
(node.
getleft()
);//線索化當前結點
if(node.
getleft()
==null)
if(pre!=null&&pre.
getright()
==null)
pre=node;
//每處理乙個結點後,讓當前結點成為剛剛訪問過的結點
//線索化右子樹
inthreadnode
(node.
getright());}
1.1.2 中序線索二叉樹的遍歷因為線索化後, 各個結點指向有變化, 因此原來的遍歷方式不能使用, 需要使用新的方式遍歷線索化二叉樹。中序線索二叉樹的結點中隱含了線索二叉樹的前驅和後繼資訊。在對其遍歷時,需要找到第乙個具有前驅結點的左結點,然後依次找結點的後繼。在中序線索二叉樹中找結點後繼的規律是:若其右標誌為1,則右鏈為線索,指示其後繼,否則遍歷右子樹中第乙個訪問的結點(右子樹中最左下的結點)為其後繼。
public
static
void
inthreadlist
(node node)
system.out.
println
(node)
;//列印當前結點
while
(node.
getrtag()
==1) node=node.
getright()
;//依次替換遍歷的結點
}}
1.1.3 中序線索二叉樹完整**
package tree;
public
class
inthreadedbinarytree
}class
node
public
intgetdata()
public
void
setdata
(int data)
public string getname()
public
void
setname
(string name)
public node getleft()
public
void
setleft
(node left)
public node getright()
public
void
setright
(node right)
public
intgetltag()
public
void
setltag
(int ltag)
public
intgetrtag()
public
void
setrtag
(int rtag)
@override
public string tostring()
}//中序線索化二叉樹(左->根->右)
class
inthreadbinarytree
public
static
void
inthreadnode
(node node)
//線索化左子樹
inthreadnode
(node.
getleft()
);//線索化當前結點
if(node.
getleft()
==null)
if(pre!=null&&pre.
getright()
==null)
pre=node;
//每處理乙個結點後,讓當前結點成為剛剛訪問過的結點
//線索化右子樹
inthreadnode
(node.
getright()
);}//中序線索化二叉樹的遍歷(遍歷次序和中序遍歷保持一致)
public
static
void
inthreadlist
(node node)
system.out.
println
(node)
;//列印當前結點
while
(node.
getrtag()
==1) node=node.
getright()
;//依次替換遍歷的結點}}
}
執行結果:
node [data=
1, name=h]
node [data=
2, name=d]
node [data=
3, name=i]
node [data=
4, name=b]
node [data=
5, name=e]
node [data=
7, name=a]
node [data=
8, name=f]
node [data=
9, name=c]
node [data=
10, name=j]
node [data=
11, name=g]
node [data=
12, name=k]
該例項的二叉樹圖如下圖所示:
2.1、前序線索二叉樹和後序線索二叉樹
二叉樹之 線索二叉樹
二叉樹是一種非線性結構,遍歷二叉樹幾乎都是通過遞迴或者用棧輔助實現非遞迴的遍歷。用二叉樹作為儲存結構時,取到乙個節點,只能獲取節點的左孩子和右孩子,不能直接得到節點的任一遍歷序列的前驅或者後繼。為了儲存這種在遍歷中需要的資訊,我們利用二叉樹中指向左右子樹的空指標來存放節點的前驅和後繼資訊 對於n個結...
樹 二叉樹 線索二叉樹
一 線索二叉樹 1 什麼是線索化 將二叉樹以某種次序將其遍歷,得到線性序列,就是將非線性結構進行線索化。線索化的優點就是可以很快地得到前驅或後繼。如果儲存線索化的線性序列 儲存二叉樹地線索化序列的其中一種方法就是在結點上加兩個指標,乙個指向前驅乙個指向後繼,這樣的缺點就是儲存密度大大降低。另一種方法...
二叉樹鏈式儲存結構
由二叉樹定義得知,二叉樹的結點由乙個元素和分別指向其左 右子樹的兩個分支構成,則表示二叉樹的鍊錶中的結點至少包含3個域,如下圖。二叉樹建立 程式是如何建立出二叉樹的?以下圖為例 從主函式開始執行 定義乙個bitnode型別的指標root,將指標root的位址賦給t t是乙個bitnode型別指標的指...