线索二叉树
二叉树的作为存储结构时不能直接获取前驱后继的信息,为此通过对二叉树线索化来构造线索二叉树,从而存储结点的前驱后继信息。
构建线索二叉树有两种选择,一是增设两个指针域,但此行会使存储密度大大降低;二是利用二叉树的未被使用的空链域来存储前驱后继信息。(总结点为n的二叉树的空链域为n+1,一开始不明白为什么是n+1个,看了其他博客才发现证明其实很简单,每个结点都有其通向的分支,每个分支都表该指针域已被利用,若二叉树的结点为n,则其总指针域为2n,则其分支为n-1,也就意味着被利用的指针域为n-1,总指针域(2n)-被利用指针域(n-1)=未被利用的指针域(n+1))
我们一般选择后者构建线索树。
中序线索化
void InThread(BiThTree p)
{
if(p)
{
InThread(p->L);
if(!p->L)
{
p->LTag=1;
p->L=pre;
}
else
{
p->LTag=0;
}
if(!pre->R)
{
pre->RTag=1;
pre->R=p;
}
else
{
pre->RTag=0;
}
pre=p;
InThread(p->R);
}
return ;
}
带头节点中序线索化
//头节点使得我们能够直接正向遍历二叉序列
void InOrderThread(BiThTree &head,BiThTree T)
{
head=malloc(sizeof(BiNode));
head->LTag=0;
head->RTag=1;
head->R=head;
if(!T)
{
head->L=head;
}
else
[
head->L=T;
pre=head;
InThread(T);
pre->R=head;
pre->RTag=1;
head->R=pre;
]
return ;
}
中序遍历线索二叉树
void InOrderTraverse(BiThTree T)
{
p=T->L;
while(p!=T)
{
while(p->LTag==0)
{
p=p->L;
}
printf("%d",p->data);
while(p->RTag==1&&p->R!=T)
{
p=p->R;
printf("%d",p->data);
}
p=p->R;
}
return ;
}
优势
1.每个结点都拥有前驱和后继信息。
2.无需栈的操作,节省了时间与空间。
3.遍历线索二叉树的时间复杂度为O(n),空间复杂度为O(1).
先序线索化树上找前驱和后序线索化树上找后继时都比较复杂,必要时可增设两个指针域。