線索二叉樹,或者說,對二叉樹線索化,實質上就是遍歷一棵二叉樹,在遍歷的過程中,檢查當前結點的左、右指針域是否爲空。如果爲空,將它們改爲指向前驅結點或後繼結點的線索。
當以二叉鏈表作爲存儲結構時,只能找到左右孩子信息,而不能直接得到結點在任意序列中的前驅和後繼信息,這種信息只有在遍歷的動態過程中才能得到。 解決此問題最簡單的辦法是在每個節點上增加兩個指針域fwd和bkwd,分別指示結點依任意次序遍歷時得到前驅和後繼信息。顯然這樣做使得結構的存儲密度 大大降低,另一方面,在有n個結點的二叉鏈表中必定存在n+1個空鏈域。由此設想能否利用這些空鏈域來存放前驅和後繼信息。
試做如下規定:若結點有左子樹,則其lchild域指向其左孩子,否則域指示其前驅,若結點有右子樹,則其rchild域指示其右孩子,否則令rchild指示其後繼。爲了避免混淆,尚需改變結點結構,增加兩個標誌域。
lchild LTag data RTag rchild
其中:
LTag=0 lchild域指示結點的左孩子
LTag=1 lchild域指示結點的前驅
RTag=0 rchild域指示結點的右孩子
RTag=1 rchild域指示結點的後繼
以這種結點結構構成的二叉鏈表作爲二叉樹的存儲結構,叫做線索鏈表,其中指向結點前驅和後繼的指針,叫做線索。加上線索的二叉樹稱爲線索二叉樹。對二叉樹進行某種次序遍歷使其變爲線索二叉樹的過程叫做線索化。
頭文件:
/*****************************************************************************************************
*Copyright: Yue Workstation
*
*FileName: IndexTree.h
*
*Function: 線索二叉樹數據結構定義
*
*Author: Abel Lee
*
*CreateOn: 2012-2-19
*
*Log: 2012-2-19 由Abel Lee創建
*****************************************************************************************************/
#ifndef INDEX_TREE_H
#define INDEX_TREE_H
#include "global.h"
typedef enum{Link,Thread} PointerTag; //指針標誌
typedef int DataType;
typedef struct BiThreTree
{ //定義結點元素
PointerTag LTag,RTag;
DataType data;
struct BiThreTree *lchild,*rchild;
}BiThreTree;
BiThreTree *pre; //全局變量,用於二叉樹的線索化
BiThreTree *CreateTree(void);
void InThread(BiThreTree *T);
BiThreTree *InOrderThrTree(BiThreTree *T);
void InThrTravel(BiThreTree *Thre);
#endif
源文件:
/*****************************************************************************************************
*Copyright:Yue Workstation
*
*FileName: IndexTree.c
*
*Function: 線索二叉樹操作
*
*Author:Abel Lee
*
*CreateOn:2012-2-19
*
*Log:2011-5-3 由Abel Lee創建
*****************************************************************************************************/
#include "../inc/IndexTree.h"
/****************************************************************************************************
*Function Name: CreateTree
*
*Function: 按先序輸入建立二叉樹
*
*Parameter: 無
*
*Return Value:成功返回樹的指針,失敗返回NULL
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
BiThreTree *CreateTree(void)
{
BiThreTree *T;
DataType e;
scanf("%d",&e);
if(e==0)
{
T=NULL;
}
else
{
T=(BiThreTree *)malloc(sizeof(BiThreTree));
T->data=e;
T->LTag=Link; //初始化時指針標誌均爲Link
T->RTag=Link;
T->lchild=CreateTree();
T->rchild=CreateTree();
}
return T;
}
/****************************************************************************************************
*Function Name: InThread
*
*Function:
*
*Parameter: 無
*
*Return Value:成功返回樹的指針,失敗返回NULL
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void InThread(BiThreTree *T)
{
BiThreTree *p;
p=T;
if(p)
{
InThread(p->lchild);
if(!p->lchild)
{
p->LTag=Thread;
p->lchild=pre;
}
if(!pre->rchild)
{
pre->RTag=Thread;
pre->rchild=p;
}
pre=p;
InThread(p->rchild);
}
}
/****************************************************************************************************
*Function Name: InOrderThrTree
*
*Function: 中序線索化二叉樹
*
*Parameter: T:二叉樹指針
*
*Return Value:成功返回樹的指針,失敗返回NULL
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
BiThreTree *InOrderThrTree(BiThreTree *T)
{
BiThreTree *Thre; //Thre爲頭結點的指針
Thre=(BiThreTree *)malloc(sizeof(BiThreTree));
if(Thre == NULL)
{
perror("Thre == NULL,malloc error!\n");
return NULL;
}
Thre->lchild=T;
Thre->rchild=Thre;
pre=Thre;
InThread(T);
pre->RTag=Thread;
pre->rchild=Thre;
Thre->rchild=pre;
return Thre;
}
/****************************************************************************************************
*Function Name: InThrTravel
*
*Function: 中序遍歷二叉樹
*
*Parameter: Thre:二叉樹指針
*
*Return Value:成功返回樹的指針,失敗返回NULL
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void InThrTravel(BiThreTree *Thre)
{
BiThreTree *p;
p=Thre->lchild;
while(p!=Thre) //指針回指向頭結點時結束
{
while(p->LTag==Link)
p=p->lchild;
printf("%4d",p->data);
while(p->RTag==Thread&&p->rchild!=Thre)
{
p=p->rchild;
printf("%4d",p->data);
}
p=p->rchild;
}
}