小孱弱弱又来了,今天分享的是二叉树的应用-线索二叉树,在我们用二叉链表时,有这样一个问题,只有一个孩子的结点和叶子结点,会有大量空余指针域,这无疑是巨大的浪费,,我们前辈们就设计出来线索二叉树,线索二叉树就是在每个结点加上两条线索,一个指向它的中序遍历前驱,一个指向它的中序遍历的后继,若不存在前驱或者后继,指向NULL,我们对以某种次序遍历使其变为线索二叉树的过程叫做线索化。为了区分指针是指向哪,我们设置两个布尔型变量,ltag和rtag,ltag为0表示指向左孩子,为1那就指向前驱,同样的rtag为0指向右孩子,为1指向它的后继。
也就是说每个结点包含左孩子域、ltag、数据域、rtag和右孩子域,一共五个域,如果才用的二叉树经常需要遍历和查找序列的前驱和后继,那么采用线索二叉链表就很不错哦。
下面上代码:
//线索二叉树的定义
typedef enum{Link,Thread}PointerTag;
typedef struct BiThrNode
{
int data;
struct BiThrNode*lchild,*rchild;
PointerTag LTag,RTag;
}BiThrNode,*BiThrTree;
//中序遍历线索化算法
BiThrTree pre;//设置一个工作指针,指向最近一个访问的结点
void InThreading(BiThrTree p)
{
if(p)
{
InThreading(p->lchild);
if(!p->lchild)
{
p->LTag=Thread;
p->lchild=pre;
}
if(!pre->rchild)
{
pre->RTag=Thread;
pre->rchild-p;
}
pre=p;
InThreading(p->rchild);
}
}
//中序遍历线索二叉树
int InOrderTraverse_Thr(BiThrTree T)
{
BiThrTree p;
p=T->lchild;
while(p!=T)
{
while(p->LTag==Link)
{
p=p->lchild;
}
cout<<p->data;
while(p->RTag==Thread&&p->rchild!=T)
{
p=p->rchild;
cout<<p->data;
}
p=p->rchild;
}
return true;
}