首先我們回憶一下二叉樹的前中後序遍歷方式:
先序遍歷序列:1 2 4 5 3 6
中序遍歷序列:4 2 5 1 6 3
後序遍歷序列:4 5 2 6 3 1
我們通過這樣的遍歷,由乙個樹形結構得到了乙個線性的結構(遍歷序列)。在這個線性序列中,除了第乙個結點和最後乙個結點,每個結點都擁有乙個前驅和後繼。
那麼在二叉樹中,我們能不能不只體現結點的父子關係,也引入結點的前驅後繼關係呢?
由此,我們引入了線索二叉樹。
我們之前說過二叉鍊錶,我們知道在乙個二叉鍊錶中,n個結點會有n+1個空指標。
接下來我們就利用這些空指標實現線索二叉樹。實現的過程我們稱之為線索化。
線索化十分簡單,過程就是——
利用先序序列進行線索化:
利用中序序列進行線索化:
利用後序序列進行線索化:
線索二叉樹的結點結構是:
我們在普通的二叉鍊錶中,新增了乙個標誌域l(r)tag
,
typedef
struct threadnodethreadnode,
*threadtree;
這種結點結構構成的二叉鍊錶作為二叉樹的儲存結構,成為線索鍊錶。
我們重點認識一下中序線索二叉樹,因為中序線索二叉樹在尋找前驅結點和後繼結點的時候都是很方便的。
在二叉樹的中序遍歷序列中,第乙個結點永遠是最左邊的結點,第二個結點永遠是最右邊的結點。前驅結點:後繼結點:
這幾句話可能很繞,我們結合圖和文字,認真的分析一下,就知道了:中序線索二叉樹的線索化過程:例如,結點3,3的左指標為左孩子,即結點6,結點6也是結點3的左子樹,該左子樹的最右側結點為6本身,那麼3的前驅結點為6。
我們看一下中序序列,4 2 5 1 6 3,也可得知,3的前驅結點確實為6。
void
createinthread
(threadtree t)
}void
inthread
(threadtree &p, threadtree &pre)
if(pre !=
null
&& pre-
>rchild ==
null
) pre = p;
inthread
(p->rchild, pre);}
}
使用上面的程式,我們就能實現如下的線索二叉樹的結構,
其實我們發現,還是有兩個空指標,我們會新增乙個頭結點,我們將
threadnode *
firstnode
(threadnode *p)
return p;
}threadnode *
nextnode
(threadnode *p)
else
}void
inorder
(threadnode *t)
}
線索二叉樹
當用二叉鍊錶作為二叉樹的儲存結構時,因為每個結點中只有指向其左 右兒子結點的指標,所以從任一結點出發只能直接找到該結點的左 右兒子。在一般情況下靠它無法直接找到該結點在某種遍歷序下的前驅和後繼結點。如果在每個結點中增加指向其前驅和後繼結點的指標,將降低儲存空間的效率。我們可以證明 在n個結點的二叉鍊...
線索二叉樹
1.線索二叉樹結構和操作定義 threadbintree.h 功能 線索標誌域所有值 typedef enumnodeflag 功能 線索二叉樹結構體 typedef struct threadtreethreadbintree 前驅節點指標 threadbintree previous null ...
線索二叉樹
原始碼 中序線索二叉樹 author 菜鳥 version 2014.7.23 include include include typedef char datatype using namespace std 定義線索二叉樹的結構體 typedef struct nodethreadbitreen...