线索二叉树:将空链域指向该节点的前驱或后继
存储结构
typedef struct ThreadNode{
int data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;//=0表示指向左右孩子,=1表示指向前驱或后继
}ThreadNode,*ThreadTree;
中序线索化
一边遍历一边线索化
void CreateInThread(ThreadTree T)//初始化
{
pre=NULL;
if(T!=NULL) InThread(T);
pre->rchild=NULL //处理最后一个节点
pre->rtag=1;
}
ThreadNode *pre=NULL;
void InThread(ThreadTree T)//先序,后序类似
{
InThread(T->lchild);
visit(T);
InThread(T->rchild);
}
void visit(ThreadNode *p)
{
if(p->lchild==NULL)
{
P->lchild=pre;//指向前驱
p->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL)
{
pre->rchild=p;//指向后继
pre->rchild=1;
}
pre=p;
}
先序线索化
void PreThread(ThreadTree T)
{
visit(T);
if(T->ltag==0) InThread(T->lchild);//visit会改变T的左孩子,防止转圈
InThread(T->rchild);
}
中序二叉树找后继
//找到以p为子树,中序遍历访问的第一个节点
ThreadNode *FirstNode(ThreadNode *p)//最左下角的节点
{
while(p->lchild) p=p->lchild;
return p;
}
//找节点p的后继节点
ThreadNode *NextNode(ThreadNode *p)//p后被中序遍历的第一个节点
{
if(p->rtag==0)
{
return FirstNode(p->rchild);
}
else return p->rchild;
}
利用中序线索二叉树实现中序遍历
void InOrder(ThreadTree T)
{
for(ThreadNode *p=FirstNode(T);p!=NULL;p=NextNode(p))
visit(p);
}
中序二叉树找前驱
若p->lchild==0则前驱是左子树最后一个被访问的节点(左子树最右)
ThreadNode *LastNode(ThreadNode *p)
{
while(p->rchild) p=p->rchild;
return p;
}
//找节点p的前驱节点
ThreadNode *PreNode(ThreadNode *p)//p后被中序遍历的第一个节点
{
if(p->ltag==0)
{
return LasttNode(p->lchild);
}
else return p->lchild;
}
逆向中序遍历
void RevOrder(ThreadTree T)
{
for(ThreadNode *p=LastNode(T);p!=NULL;p=PreNode(p))
visit(p);
}