线索二叉树的主要操作,包含:以p为根节点的子树中序线索化,带头结点的二叉树中序线索化和遍历线索二叉树这几个函数。
下面讲一下实现代码:
首先,依然是类型定义,并声明一个全局变量pre:
typedef char ElemType;
typedef struct BiThrNode{
ElemType data;
BiThrNode *lchild, *rchild;
int LTag, RTag;
}BiThrNode,*BiThrTree;
BiThrTree pre;
带头结点的二叉树中序线索化:
BiThrNode *InOrderThreading(BiThrTree T)
{
BiThrTree Thrt, p;
Thrt = (BiThrNode *)malloc(sizeof(BiThrNode));
Thrt->LTag = 0;
Thrt->RTag = 1;
Thrt->rchild = Thrt;
if (!T)
Thrt->lchild = Thrt;
else
{
Thrt->lchild = T;
pre = Thrt;
InThreading(T);
Thrt->rchild = pre;
pre->RTag = 1;
pre->rchild = Thrt;
}
return Thrt;
}
先为Thrt动态分配空间,并让Thrt->LTag=0,Thrt->Rtag=1,让Thrt的右子树指向自己。判断二叉树T是否为空树,如果为空树,则让Thrt的左子树也指向自己;否则,让其左子树指向T的根节点,并且让全局变量pre=Thrt,线索化T(利用InThreading(),下面会提供代码)。注意线索化之后Thrt的右子树指向的是二叉树T最左端的节点,pre指向的是T最右端的节点且pre的RTag尚未赋值,pre的rchild并未指向任何位置。所以让Thrt的右子树指向pre节点,让pre->Rtag=1,pre的右节点指向Thrt.最后返回Thrt的值作为树的头节点。
以p为根节点的子树中序线索化:
void InThreading(BiThrTree p)
{
if (p)
{
InThreading(p->lchild);
if (!p->lchild)
{
p->LTag = 1;
p->rchild = pre;
}
else
p->LTag = 0;
if (!pre->rchild)
{
pre->RTag = 1;
pre->rchild = p;
}
else
pre->RTag = 0;
pre = p;
InThreading(p->rchild);
}
}
先判断p子树是否为空,如果不为空,利用递归对p的左子树进行线索化。如果p的左子树为空,则让p->LTag为1,表示指向p的前驱,并且让pre赋值给p的右子树;如果不为空,则让p->LTag为0,表示指向p的后继。对pre进行同理操作。最后让pre移动到p的位置,并利用递归对p的右子树进行线索化。
遍历线索二叉树:
void InOrderTraverse_Thr(BiThrTree T)
{
BiThrTree p;
p = T->lchild;
while (p != T)
{
while (p->LTag == 0)
p = p->lchild;
printf("%c", p->data);
while (p->RTag == 1 && p->rchild != T)
{
p = p->rchild;
printf("%c", p->data);
}
p = p->rchild;
}
printf("\n");
}
先声明一个指针p,让p指向T的左子树。当p不为T的时候,则执行以下循环:当p->LTag等于0的时候,表示p的左子树不为空,则一直循环让p指向p的左子树,让p到达T最左端的叶子。输出p的data数据。然后当p->Rtag等于1并且p的右子树不等于T的时候表示p有后继并p的右子树指向其后继,此时让p移动到p的右子树的位置,输出p的data数据。让p移动到p的右子树位置。自此最外的循环结束。
创建新二叉树
BiThrNode *CreateBiTree(BiThrTree T)
{
ElemType ch;
scanf("%c", &ch);
if (ch == '#')
T = NULL;
else
{
T = (BiThrNode *)malloc(sizeof(BiThrNode));
T->data = ch;
T->lchild = CreateBiTree(T->lchild);
T->rchild = CreateBiTree(T->rchild);
}
return T;
}
加入main()测试:
int main(void)
{
BiThrTree T;
int n;
T = NULL;
printf("1.创建二叉树\n2.转换为逻辑树\n3.遍历二叉树(按逻辑结构)\n");
while (1)
{
printf("请选择:");
scanf("%d", &n);
fflush(stdin);
switch (n)
{
case 1:
T = CreateBiTree(T);
break;
case 2:
T = InOrderThreading(T);
break;
case 3:
InOrderTraverse_Thr(T);
}
}
return 0;
}