线索树的构造思路
(1)首先构造出一棵二叉树
(2)然后将二叉树线索化(1.中序2.先序3.后序)
关于二叉树的建立(方法之一)
(1)用一个字符串来表示二叉树上的元素,其中’#’代表无效结点,然后可以根据自己的需求来调整字符串顺序
char *str = “ABC##DE##F##G#H##”;
希望构建中序遍历是
C B E D F A G H
先序遍历
A B C D E F GH 的二叉树
二叉树建立函数
BinaryNode * CreateTree(char *& str)
{
BinaryNode* s = NULL;
if (*str != '#')
{
s = (BinaryNode*)malloc(sizeof(BinaryNode));
s->data = *str;
s->left = 0;
s->right = 0;
s->leftNode = CreateTree(++str);
s->rightNode = CreateTree(++str);
}
return s;
}
二叉树成功建立了以后是线索化
中序线索化
void Make(BiThrNode *p, BiThrNode *&ptr)//对一个结点
{
if (p != NULL)
{
Make(p->leftchild, ptr);
if (p->leftchild == NULL)
{//当当前p的前驱书空的时候,因为ptr是他的前驱所以可以赋值
p->leftchild = ptr;//左是前驱,右是后继
p->Ltag = THREAD;
}
if (ptr != NULL && ptr->righthchild == NULL)
{//ptr记录的是p的前驱,当前驱的后继是空的时候对前驱进行赋值
ptr->righthchild = p;
ptr->Rtag = THREAD;
}
ptr = p;
Make(p->righthchild, ptr);
}
}
void MakeThread(BiThrNode *p)
{
if (p == NULL) return;
BiThrNode *ptr = NULL;
Make(p, ptr);
ptr->righthchild = NULL;//后继
ptr->Rtag = THREAD;
}
获取线索树的第一个结点,以中序的方式
BiThrNode * First(BiThrNode *ptr)
{//查找以ptr为根节点的第一个结点,中序情况
while (ptr != NULL && ptr->Ltag != THREAD)
{
ptr = ptr->leftchild;
}
return ptr;
}
获得线索树当前结点的上一个结点
BiThrNode * Last(BiThrNode *ptr)
{//如果是线索那就直接返回,如果不是线索,按照左中右,那就找到左的最后一个
while (ptr != NULL && ptr->Rtag != THREAD)
{
ptr = ptr->righthchild;
}
return ptr;
}
获得线索树当前结点的下一个结点
BiThrNode * Next(BiThrNode *ptr)
{
if (ptr == NULL) return NULL;
if (ptr->Rtag == THREAD)
{
return ptr->righthchild;
}
else
{
return First(ptr->righthchild);
}
}
获得当前结点的上一个结点
BiThrNode * Prev(BiThrNode *ptr)
{
if (ptr == NULL) return NULL;
if (ptr->Ltag == THREAD)
{
return ptr->leftchild;
}
else
{
return Last(ptr->leftchild);//找ptr的上一个
}
}
以线索为依据的逆序中序遍历和顺序中序遍历
void ResNiceInOrder(BiThrNode *ptr)
{
for (BiThrNode *p = Last(ptr); p != NULL; p = Prev(p))
{
cout << p->data << " ";
}
cout << endl;
}
void NiceInOrder(BiThrNode *ptr)
{
for (BiThrNode *p = First(ptr); p != NULL; p = Next(p))
{
cout << p->data << " ";
}
cout << endl;
}
线索二叉树适用范围:
若在某程序中所用二叉树需经常遍历或查找结点在遍历所得线性序列中的前驱和后继,则应采用线索链表做存储结构。