(一)线索二叉树原理
线索二叉树:加上线索的二叉树
线索:结点的前驱和后继指针
空链域和非空链域:不管二叉树的形态如何,二叉树中空链域的个数总是大于非空链域的个数。有n个结点的二叉树,一共有2n个链域,n-1个非空链域,n+1个空链域。所以考虑用二叉树的空链域来存放指向结点的前驱和后继的指针。
建立线索的规则:若结点有左子树,则其lchild域指向其左孩子,否则指向其前驱;若结点有右子树,则其rchild域指向其右孩子,否则指向其后继。
显然,需要标志来判断,lchild和rchild是指向左右孩子还是指向前驱和后继,因此在每个结点增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。
结点结构:
其中:(1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;(2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;
(二)线索二叉树结构实现
2.1 二叉树的二叉线索存储结构
/*二叉树的二叉线索存储结构定义*/
typedef enum{Link,Thread} PointerTag;//Link==0 表示指向左右孩子指针
//Thread==1 表示指向前驱或后继的线索
typedef char TElemType;
typedef struct BiThrNode
{
TElemType data;//结点数据
struct BiThrNode *lchild,*rchild;//左右孩子指针
PointerTag LTag,RTag;//左右标志
}BiThrNode,*BiThrTree;
2.2 创建一个二叉树,按照前序遍历方式输入
void CreateBiThrTree(BiThrTree *T)
{
char c;
scanf_s("%c",&c);
if('#'==c)
{
T=NULL;
}
else
{
*T=(BiThrNode*)malloc(sizeof(BiThrNode));
(*T)->data=c;
(*T)->LTag=Link;
(*T)->RTag=Link;
CreateBiThrTree(&(*T)->lchild);
CreateBiThrTree(&(*T)->rchild);
}
}
2.3 中序遍历线索化
void InThreading(BiThrTree T)
{
if (T)
{
InThreading(T->lchild); //递归左孩子线索化
//结点处理
if (!T->lchild) //如果该结点没有左孩子,设置ltag为Thread,并把lchild指向刚刚访问的结点。
{
T->ltag = Thread;
T->lchild = pre;
}
if (!pre->rchild)
{
pre->rtag = Thread;
pre->rchild = T;
}
pre = T;
InThreading(T->rchild); //递归右孩子线索化
}
}
void InOrderThreading(BiThrTree *p,BiThrTree T)
{
*p = (BiThrTree)malloc(sizeof(BiThrNode));
(*p)->ltag = Link;
(*p)->rtag = Thread;
(*p)->rchild = *p;
if (!T)
{
(*p)->lchild = *p;
}
else
{
(*p)->lchild = T;
pre = *p;
InThreading(T);
pre->rchild = *p;
pre->rtag = Thread;
(*p)->rchild = pre;
}
}
void visit(char c)
{
printf_s("%c", c);
}
//中序遍历二叉树,非递归
void InOrderTraverse(BiThrTree T)
{
BiThrTree p;
p = T->lchild;
while (p != T)
{
while (p->ltag == Link)
{
p = p->lchild;
}
visit(p->data);
while (p->rtag == Thread && p->rchild != T)
{
p = p->rchild;
visit(p->data);
}
p = p->rchild;
}
}
int main()
{
BiThrTree P, T = NULL;
CreateBiThrTree(&T);
InOrderThreading(&P, T);
printf_s("中序遍历输出结果为:");
InOrderTraverse(P);
printf_s("\n");
system("pause");
return 0;
}</span>