线索二叉树用中序遍历法,利用空结点存放前驱与后继
线索二叉树需对普通(根左右)进行扩容
lchild | ltag | data | rtag | rchild |
• ltag为0时指向该结点的左孩子,为1时指向该结点的前驱
• rtag为0时指向该结点的右孩子,为1时指向该结点的后继
线索二叉树代码实现
#include<stdio.h>
#include<stdlib.h>
typedefchar ElemType;//定义一个通用的ElemType
//线索存储标志位,Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱后继的线索
typedefenum {Link, Thread}//定义枚举类型
typedefstruct BiThrNode //定义一个结构, 表示结点
{
char data;
struct BiThrNOde *lchuld, *rchild;//以同样的结构递归定义左、右孩子
PointerNag ltag;//用来标志左孩子
PointerNag rtag;//用来标识右孩子
}BiThrNode,*BiThrTree;
//全局变量,时钟访问刚刚访问过的结点
BiThrTreepre;
//创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
CreatBiThree(CreateBiThrTree*T)
{
char c;
scanf(“%c”, &c);
if(‘ ‘ == c)
{
*T = NULL;
}
else
{
*T = (BiThrNode *)malloc(sizeof(BiThrNode));
(*T) -> data = c;
(*T) -> rtag = Link;
CreateBiThrTree(&(*T) -> lchild);
CreateBiThrTree(&(*T)-> rchild);
}
}
//中序遍历代码(线索二叉树)
InThreading(BiThreeT)
{
if(T)//判断不是空树(树存在)
{
InThreading(T -> lchild);//递归左孩子线索化
//结点处理
if(!T -> lchild) //如果该结点没有左孩子,这只Ltag为Three,并把lchild指向刚刚访问的结点
{
T -> ltag = Thread;
T -> child = pre;
}
if(!pre -> rchild)
{
pre -> rtag = rchild;
pre -> rchild = T;
}
pre = T;
InThreading(T -> rchild);//递归右孩子线索化
}
}
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;
}
voidvisit(char c)
{
printf(“%c\n”, c);
}
//中序遍历二叉树,非递归
voidInOrderTraverse(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;
}
}
intmain()
{
BiThree p, T = NULL;
CreateBiThrTree(&T);
InOredrThreading(&p,T);
printf(“中序遍历输出结果为:”);
InOrderTraverse(p);
return 0;
}