struct TBTNode
{
char data;
TBTNode* lchild;
TBTNode* rchild;
int ltag,rtag;
};//TBTNode与BTNode相差了ltag和rtag分别代表左边和右边是否为线索;如果左边是线索,那么ltag=1,否则为0;如果右边是线索,那么rtag=1,否则为0;
TBTNode* pre;//代表线索化中的前一个访问节点
void Thread(TBTNode* &p)//输入根节点,建立线索化;
{
if(p!=NULL)//这里用了递归,有点难理解;其实递归是整体与局部的关系,这里可以假设只有三个节点,根节点,根节点的左节点和右节点
{
Thread(p->lchild);//线索化根节点的左节点,此时pre会被赋值为左节点,p为当前根节点,下面对pre和p节点线索
if(p->lchild==NULL)//如果左节点为空,那么将左孩子指针指向前驱节点pre;
{
p->ltag=1;
p->lchild=pre;
}
else
p->ltag=0;
if(pre->rchild==NULL)//如果pre的右节点为空,那么右孩子指针指向直接后继p
{
pre->rchild=p;
pre->rtag=1;
}
else
pre->rtag=0;
pre=p;//此时pre变成了p节点
Thread(p->rchild);//对p节点的右节点线索化
}
}
TBTNode* CreateThread(TBTNode* &b)
{
TBTNode* root;
root=(TBTNode*)malloc(sizeof(TBTNode));//构造头节点
root->ltag=0;//左指针指向根节点
root->rtag=1;//右指针用来线索
root->rchild=b;//如果此时,只有一个节点(即根节点),那么右指针指向最后一个节点即根节点
if(b==NULL)//如果,头结点为空,那么左指针指向自己
root->lchild=root;
else//将pre赋值为root,然后线索化
{
root->lchild=b;
pre=root;
Thread(b);
pre->rchild=pre;//此时的pre为中序遍历的最后节点,那么将它的右指针指向头节点
pre->rtag=1;//rtag表示线索
root->rchild=pre;//将头结点的右指针线索指向最后节点pre;
return root;//返回头节点
}
}
void ThInOrder(TBTNode* tb)//这是遍历线索二叉树
{
TBTNode* p=tb->lchild;//p指向根节点
while(p!=tb)
{
while(p->ltag==0) p=p->lchild;//找到中序遍历中的第一个节点
cout<<p->data<<endl;//输出该节点的值
while(p->ltag==1 && p->rchild!=tb)//循环找其后继节点(如果存在线索,即rtag=1,并且不是最后个节点)
{
p=p->rchild;
cout<<p->data<<endl;
}
p=p->rchild;//如果rtag=0,有右节点,那么重新赋值p,去找下个节点
}
}