注意事项:
- 二叉链表被线索化之后可以不需要使用栈来遍历链表,当先序遍历时没有左结点就访问右结点所指的后继。
- 若在某程序中所用二叉树需经常遍历或查找结点在遍历所得线性序列中的前驱和后继,则应采用线索链表作为存储结构
- 普通二叉链表不需要头结点,而线索二叉树需要,为了第一个结点指针有找落点,如果第一个指针和最后一个都指向头结点,即二叉树为空。
- 由于线索二叉树是在遍历的过程中得到的,所以不同的遍历方法有不同的线索二叉树,因为指针域是公用的,所以为了区别开,另外设置了两个标志域
#include<stdio.h>
typedef struct BiThrNode
{
int data;
struct BiThrNode *lchild, *rchild;
int LTag, RTag;
}BiThrNode, *BiThrTree;
BiThrTree pre;
void Creat(BiThrTree *t);
void InOrderThreading(BiThrTree *Thrt, BiThrTree T);
void InThreading(BiThrTree p);
void InOrderTraverse(BiThrTree T);
void InOrder(BiThrTree t);
int main()
{
BiThrTree b;
BiThrTree t;
Creat(&t);
printf("Using the origin is :\n");
InOrder(t);
printf("NULL\n");
InOrderThreading(&b, t);
InOrderTraverse(b);
printf("NULL\n");
}
void InOrder(BiThrTree t)
{
if (t)
{
InOrder(t->lchild);
printf("%c->", t->data);
InOrder(t->rchild);
}
}
void Creat(BiThrTree *t)
{
char ch;
scanf_s("%c", &ch);
if (ch == ' ')
(*t) = NULL;
else
{
(*t) = (BiThrTree)malloc(sizeof(BiThrNode));
(*t)->data = ch;
Creat((&(*t)->lchild));
if ((*t)->lchild)
(*t)->LTag = 0;
Creat((&(*t)->rchild));
if ((*t)->rchild)
(*t)->RTag = 0;
}
}
void InOrderThreading(BiThrTree *Thrt, BiThrTree T)
{
if (!((*Thrt) = (BiThrTree)malloc(sizeof(BiThrNode))))
return;
(*Thrt)->LTag = 0;
(*Thrt)->RTag = 1;
(*Thrt)->rchild = (*Thrt);
if (!T)
(*Thrt)->lchild = (*Thrt);
else
{
(*Thrt)->lchild = T;
pre = (*Thrt);
InThreading(T);
pre->rchild = (*Thrt);
pre->RTag = 1;
(*Thrt)->rchild = pre;
}
}
void InThreading(BiThrTree p)
{
if (p)
{
InThreading(p->lchild);
if (!p->lchild)
{
p->LTag = 1;
p->lchild = pre;
}
if (!pre->rchild)
{
pre->RTag = 1;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild);
}
}
void InOrderTraverse(BiThrTree T)
{
BiThrTree 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;
}
}