在具体应用中,有时需要访问二叉树中的结点在某种遍历序列中的前驱和后继,为方便并效率地使用,我们可以利用原二叉树上没有使用的空指针域。若左指针为空,则指向前驱,若右指针为空则指向后继。线索表的结点结构类型为:
enum flag{Child,Thread};
template<class Type>
struct ThrNode
{
Type data;
ThrNode<Type> * lchild,* rchild;
flag ltag,rtag;
};
二叉树的遍历有四种,故线索化二叉树也有四种:前序线索链表,中序线索链表,后序线索链表,层序线索链表。下面的例子以中序线索链表为例。
建立二叉链表(带线索标志):
ThrNode<Type> * InThrBiTree<Type>::Create(ThrNode<Type> * cur)
{
Type ch;
if (ch == '#')
cur = NULL;
else
{
cur = new ThrNode;
cur->data = ch;
cur->ltag = 0;
cur->rtag = 0;
cur->lchild = Create(cur->lchild);
cur->rchild = Create(cur->rchild);
}
return cur;
}
中序线索化链表:
template<class Type>
void InThrBiTree<Type>::ThrBiTree(ThrNode<Type> * cur,ThrNode<Type> * pre)
{
if (cur == NULL)
return;
ThrBiTree(cur->lchild,pre);
if (cur->lchild == NULL)
{
cur->ltag = 1;
cur->lchild = pre;
}
if (cur->rchild == NULL)
cur->rtag = 1;
if (pre->rtag == 1)
pre->rchild = cur;
pre = cur;
ThrBiTree(cur->rchild,pre);
}
中序线索链表查找后继算法:
template<class Type>
ThrNode<Type> * InThrBiTree<Type>::Next(ThrNode<Type> * cur)
{
ThrNode<Type> * temp;
if (cur->rtag == 1)
temp = cur->rchild;
else
{
temp = cur->rchild;
while (temp->ltag == 0)//查找最左下结点
temp = temp->lchild;
}
return temp;
遍历:
template<class Type>
void InThrBiTree<Type>::InOrder()
{
ThrNode<Type> * temp;
if (root == NULL)
return ;
temp = root;
while (temp->ltag == 0)
temp = temp->lchild;
cout<<temp->data;
while (temp->rchild != NULL)//存在后继则继续访问后继结点
{
temp = Next(temp);
cout<<temp->data;
}
}