线索二叉树就是增加了线索的二叉树,那么什么是线索呢?线索就是事情发展的头绪和脉络,能够作为二叉树的头绪和脉络的,自然就是指向ta的前驱和后继的指针。
简而言之:我们把指向前驱和后继的指针的称为线索,加上线索的链表就是线索链表例如双向链表,加上了线索的二叉树,自然就是线索二叉树了。
线索二叉树的实现在于定义两个指针指向前驱和后继,那么,怎么告诉计算机爸爸ta有没有前驱和后继呢?我看书上的办法是增加俩变量ltag和rtag。
当ltag为0时,指向该节点的左孩子,为1时指向该节点的前驱。
当rtag为0时,指向该节点的右孩子,为1时指向该节点的后驱。
线索化的过程就是在遍历中修改指针的过程、
//线索二叉树的代码复制
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
typedef enum {Link, Thread} Pointertag;//enum 枚举定义Link, Thread,
//① 枚举元素不是变量,而是常数,因此枚举元素又称为枚举常量。因为是常量,所以不能对枚举元素进行赋值。
// 枚举元素作为常量,它们是有值的,C 语言在编译时按定义的顺序使它们的值为0,1,2,…。
//所以Link==0,Thread==1
typedef struct BiThrNode{
char date;
struct BiThrNode *lchild,*rchild;
Pointertag ltag; //左右标志
Pointertag rtag;
}BiThrNode, *BiThrTree;
void create_tree(BiThrTree *);
void Inthreading(BiThrTree); //线索化没有改变结点的值,只是在结点
//中序遍历线索化二叉树
void InOrderTraverse (BiThrTree);
int main(){
BiThrTree pT;
create_tree(&pT);
printf ("!!!!!!!!!!!!");
Inthreading(pT);
printf ("!!!!!!!!!!!!");
InOrderTraverse (pT);
return 0;
}
void create_tree(BiThrTree *pT){
char ch;
scanf("%c", &ch);
if (ch =='#')
{
*pT = NULL;
}
else{
*pT= (BiThrTree)malloc(sizeof(BiThrNode));
if (*pT==NULL)
{
exit(1);
}
(*pT) ->date=ch;
create_tree(&(*pT)->lchild);
create_tree(&(*pT)->rchild);
}
}
BiThrTree pre;//全局变量,始终指向刚刚访问过的结点
void Inthreading(BiThrTree p){
if (p){
Inthreading(p->lchild);
if (NULL==p->lchild){
p->ltag = Thread;
p->lchild = pre;printf("12345679\n");
}
if (NULL==pre->rchild){
pre->rtag = Thread;
pre->rchild = p;printf("1234567910\n");
}
pre=p;
printf("123456791111");
Inthreading(p->rchild);
}
}
void InOrderTraverse (BiThrTree T){
BiThrTree p;
p = T -> lchild;
while(p!=T){
while (p->ltag==Link){
p->lchild;
printf("%c", p->date);
}
while (p->rtag==Thread && p->rchild!=T){
p = p->rchild;
printf("%c", p->date);
}
p = p->rchild;
}
return;
}