概念
線索二叉樹:按照某種遍歷方式對二叉樹進行遍歷,可以把二叉樹中所有結點排序爲一個線性序列。在改序列中,除第一個結點外每個結點有且僅有一個直接前驅結點;除最後一個結點外每一個結點有且僅有一個直接後繼結點。這些指向直接前驅結點和指向直接後續結點的指針被稱爲線索(Thread),加了線索的二叉樹稱爲線索二叉樹。
百科解釋:鏈接
完整C++代碼:
#include <iostream>
using namespace std;
//線索二叉樹的鏈式儲存結構
typedef struct BiThrNode
{
char ch; // 數據
struct BiThrNode *lChild, *rChild; // 左右子樹
bool LTag, RTag; //左右線索標誌
}BiThrNode, *BiThrTree;
BiThrTree pre; // 前驅節點,用來生成線索二叉樹
/*
* 創建一個二叉樹節點
* 返回創建的新節點
*/
BiThrTree CreateBiThrNode(char ch)
{
BiThrTree newT = new BiThrNode;
newT->ch = ch;
newT->lChild = newT->rChild = NULL;
newT->LTag = newT->RTag = false;
return newT;
}
/*
* 創建二叉樹
* 根據輸入先序創建二叉樹, 輸入 # 表示爲空樹
*/
void CreateBiThrTree(BiThrTree &rootT)
{
char ch;
cin >> ch;
if('#' == ch){
rootT = NULL;
}
else{
rootT = CreateBiThrNode(ch);
CreateBiThrTree(rootT->lChild);
CreateBiThrTree(rootT->rChild);
}
}
/*
* 二叉樹的中序線索化
* 中序遍歷依次改寫指針
*/
void InThreading(BiThrTree rootT)
{
if(rootT){
InThreading(rootT->lChild); //線索化左子樹
// 改寫左線索指針
if(rootT->lChild == NULL){
rootT->LTag = true;
rootT->lChild = pre;
}else{
rootT->LTag = false;
}
// 改寫右線索指針
if(pre->rChild == NULL){
pre->RTag = true;
pre->rChild = rootT;
}else{
pre->RTag = false;
}
pre = rootT; // 記錄前驅節點
InThreading(rootT->rChild); // 線索化右子樹
}
}
/*
* 二叉樹的中序線索化
* 返回頭節點
*/
BiThrTree InOrderThreading(BiThrTree rootT)
{
BiThrTree firstT = CreateBiThrNode('#');
firstT->LTag = false;
firstT->RTag = true;
if(rootT == NULL){
firstT->rChild = firstT; // 樹爲空,則右線索指向自己
}else{
firstT->lChild = rootT; // 左線索指向樹根節點
pre = firstT;
InThreading(rootT);
// 最後節點的右線索指針指向頭節點
pre->rChild = firstT;
pre->RTag = true;
firstT->rChild = pre; // 右線索指向最後訪問的節點
}
return firstT;
}
/*
* 中序遍歷線索二叉樹
* 重複:輸出節點數據,獲取後繼節點
*/
void InOder_Traverse_Thr(BiThrTree firstT)
{
BiThrTree pT = firstT->lChild; //獲取根節點
while(pT != firstT){
// 沿左孩向子下
while(! pT->LTag){
pT = pT->lChild;
}
cout << pT->ch << " ";
// 沿右線索訪問後繼節點
while(pT->RTag && pT->rChild != firstT){
pT = pT->rChild;
cout << pT->ch << " ";
}
pT = pT->rChild; // 轉向右子樹
}
}
int main()
{
BiThrTree rootT;
CreateBiThrTree(rootT);
BiThrTree firstT = InOrderThreading(rootT);
InOder_Traverse_Thr(firstT);
return 0;
}
銷燬的操作沒有寫,但對於這個程序,這點內存泄露也沒什麼影響(^_^)
這裏只給出了中序線索化及遍歷方法,其它的就不寫了(^_^)
參考博文:http://blog.csdn.net/jiajiayouba/article/details/9224403