我们把这种指向前驱和后继的指针称为线索,加上线索的二链表称为线索链表,相应的二叉树就称为线索二叉树;
存储;
/二叉树的二叉线索储存结构的定义/
typedef enum {Link ,Thread} pointerTag ; /* link==0表示指向左右孩子的指针/*
typedef struct BiThrNode
{
int data /*结点数据*/
struct BiThrNode *lchild ,*rchild;
pointerTag LTag; /*左右标志*/
pointerTag RTag;
}BiThrNode ,*BiThrTree;
中序遍历线索化的递归代码;
1`
void InThreading(BiThrTree p)
{
BiThree pre; // 申请一个指针;
if(p)
{
InThreading(p->lchild)
if(!p->lchild)
{
p->LTag=Thead // (1)前驱线索
p->lchild=pre // 左孩子指向前驱
}
if(pre!=NULL && pre->rchild==NULL)
{
pre->RTag=Thread
pre->rchild=p; //前驱有孩子指向后继
}
pre=p;
InThreading(p->child);
}
if (!p->lchild) 表示当p->lchild 为空时, p的前驱为 pre,链接前后 p-lchild=pre 设置为标志;
后继时,p的后继还没有访问到,判断 pre->rchild==NULL 是否成立,成立则,pre->rchild=p 设置为标志;
- 将所有的p->rchild==NULL为空时找到它的后继;
- 将所有的p->lchild==NULL 为空时找到他的前驱结点;
- 始得遍历的单链表由类单链表变为类双链表;
效果图
增设头结点;
增设头结点
在线索二叉链表上添加一个head结点,并令其lchild域的指针指向二叉树的根结点(A),其rchild域的指针指向中序遍历访问的最后一个结点(G)。同样地,二叉树中序序列的第一个结点中,lchild域指针指向头结点,中序序列的最后一个结点rchild域指针也指向头结点。
于是从头结点开始,我们既可以从第一个结点顺后继结点遍历,也可以从最后一个结点起顺前驱遍历。就和双链表一样
//为线索二叉树添加头结点,使之可以双向操作
Status InOrderThreading(BiThrTree *Thrt, BiThrTree T){
BiThree *Thrt;
if(!(*Thrt = (BiThrTree)malloc(sizeof(BiThrNode)))) exit(OVERFLOW); //申请空间是否成功;
// 初始化头节点,有后继无前驱;
(*Thrt)->LTag = Link;
(*Thrt)->RTag = Thread; //设置标志域
(*Thrt)->rchild = (*Thrt); //右结点指向本身
if(!T) {
(*Thrt)->lchild = (*Thrt);
return OK; //若根结点不存在,则该二叉树为空,让该头结点指向自身.
}
BiThrTree pre; //设置前驱结点
//令头结点的左指针指向根结点
pre = (*Thrt);
(*Thrt)->lchild = T;
//开始递归输入线索化
InThreading(T,&pre);
//此时结束了最后一个结点的线索化了,下面的代码把头结点的后继指向了最后一个结点.
//并把最后一个结点的后继也指向头结点,此时树成为了一个类似双向链表的循环.
pre->rchild = *Thrt;
pre->RTag = Thread;
(*Thrt)->rchild = pre;
return OK;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。