建立线索二叉树其实就是二叉树的线索化,在这里就不详细讲原理了,构建的方法书上都有,在这主要对代码分析。
首先先是对线索二叉树的声明:
#include<stdio.h>
typedef char ElemType;
typedef struct bthnode
{
ElemType data;
struct bthnode *lchild,rchild;
int ltag,rtag;
}BthNode;
其中和二叉树不一样的地方就是多了两个整型的ltag和rtag,其实是为了区分左右结点是指向左右孩子还是指向前驱或者后继。
接下来我们首先创建一个头结点head,头结点的data域为空,只用他的左右孩子域:
BthNode *CreaThread(BthNode *bt)
{
BthNode *head;
head=(BthNode *)malloc(sizeof(BthNode));
head->ltag=0;head->rtag=1;
head->rchild=bt;
创建好之后将它右孩子域指向bt这个二叉树,先要判断若这个二叉树为空,则
{
head->ltag=0;head->lchild=head;
head->rtag=1;head->rchild=NULL;
}
若不为空,将头结点的左孩子指向二叉树首结点。开始遍历;
重点来了!!!
我们把这个中序遍历法来插入线索的函数写出来。
BthNode *pre;
void Thread(BthNode *&p)
{
if(p!=NULL)
{
Thread(p->lchild);
if(p->lchild==NULL;)
{
p->lchild=pre;
p->ltag=1;
}
else p->ltag=0;
if(pre->rchild==NULL)
{
pre->rchild=p;
pre->rtag=1;
}
else pre->rtag=0;
pre=p;
Thread(p->rchild);
}
}
先定义一个全局变量pre,它是p的前驱;然后在遍历函数中用p逐一从第一个开始按中序遍历顺序往后移动。当这个结点p不为空时开始执行。
Thread(p->lchild);就是一路向左,递归知道最后一个左孩子(叶子)找到,并对它经行线索化。一开始我们让pre指向头结点。以下图为例,中序遍历顺序:(DBEAC)
p指向D,pre指向头结点:
它的左孩子为空,则让它指向pre,并且ltag为1;
它的pre右孩子不为空,则让rtag为0;
之后将pre赋为p,因为D左右孩子都为空,所以Thread(p->lchild);和Thread(p->rchild);直接跳过。
回到上一个递归,
p指向B,pre指向D:
B的左孩子域不为空,ltag=0;
B的pre右孩子域为空,D的右孩子域指向B,rtag=1;(表示的意思就是D的后继为B)
pre=p,对B->rchild(E)分析:
P指向E,pre指向B;
E的左孩子域为空,则让它指向pre(B)(意思就是表达E的前驱的B),ltag=1;
pre的右孩子不为空,rtag=0;(就是本来要表示B的后继是E,但B右孩子存了E,所以存不下了)
再重新pre=p,回到上一个递归.........................后面的都一样,就不一一说了。
这个函数写好后就开始调用它:完成最后的收尾工作:
else
{
head->lchild=bt;
pre=head;
Thread(bt);
pre->rchild=head;
pre->rtag=1;
head->rchild=pre;
}
return head;//全部线索化好了,将头结点返回
}
将遍历的最后一个结点的右孩子域指向头结点,将头结点的右孩子域指向最后一个结点(这时pre就是指向最后一个结点,因为函数结尾进行了赋值)。
最后整个代码如下:
#include<stdio.h>
typedef char ElemType;
typedef struct bthnode
{
ElemType data;
struct bthnode *lchild,rchild;
int ltag,rtag;
}BthNode;
BthNode *CreaThread(BthNode *bt)
{
BthNode *head;
head=(BthNode *)malloc(sizeof(BthNode));
head->ltag=0;head->rtag=1;
head->rchild=bt;
if(bt==NULL)
{
head->ltag=0;head->lchild=head;
head->rtag=1;head->rchild=NULL;
}
else
{
head->lchild=bt;
pre=head;
Thread(bt);
pre->rchild=head;
pre->rtag=1;
head->rchild=pre;
}
return head;//全部线索化好了,将头结点返回
}
BthNode *pre;
void Thread(BthNode *&p)
{
if(p!=NULL)
{
Thread(p->lchild);
if(p->lchild==NULL;)
{
p->lchild=pre;
p->ltag=1;
}
else p->ltag=0;
if(pre->rchild==NULL)
{
pre->rchild=p;
pre->rtag=1;
}
else pre->rtag=0;
pre=p;
Thread(p->rchild);
}
}