1.线索二叉树简介
通过遍历二叉树,我们可以得到一个线性序列,其中包括前序,中序,后序等等,而其中每个结点都一一对应着前驱和后继结点(即在前序等等遍历中得到的线性序列中在某一结点前面和后面的结点)。
当二叉树以链表作为存储结构时,只能找到结点的左右孩子信息 ,而不能直接得到结点在任一序列中的前驱和后继信息,这种信息只有在遍历的动态过程中才能得到。
为此引入线索二叉树来保存这些在动态过程中得到的有关前驱和后继的信息。
2.线索二叉树原理
二叉树的结构中,指针域并没有充分的利用,其有相当数量指向了NULL。
一个有n个结点的二叉链表,每个节点都有指向左右孩子的两个指针域,一共有2n个指针域。而n个结点的二叉树又有n-1条分支线数(除了头结点,每一条分支都指向一个结点),也就是存在2n-(n-1)=n+1个空指针域。因此, 可以用空链域来存放结点的前驱和后继。线索二叉树就是利用n+1个空链域来存放结点的前驱和后继结点的信息。
3.线索二叉树结点结构
为了和正常指向其左右孩子的指针区分,我们引入ltag和rtag来辨别其左右孩子指针是否指向NULL。
typedef struct tree {
Type data; //结点数据
struct BiThrNode *lchild, *rchild; //左右孩子指针
int ltag;
int rtag; //左右标志
}treeNode, *xsTree;
ltag为0是指向该结点的左孩子,为1时指向该结点的前驱
rtag为0是指向该结点的右孩子,为1时指向该结点的后继
4.二叉树线索化代码实现
以下为前序线索二叉树
void InThread(xstree p,xsTree*pre)
{
if (p==NULL)return;
if (p->lchild==NULL)
{
p->lchild=pre;
p->ltag=1;
}
if (pre!=NULL&&pre->rchild==NULL)
{
//建立前驱节点的后继线索
pre->rchild=p;
pre->rtag=1;
}
pre=p; //pre指向当前的p,作为p将要指向的下一个节点的前驱节点提示指针
InThread(p->lchild,pre);
InThread(p->rchild,pre);
}