先理解图,在看代码。
#include <iostream>
using namespace std;
typedef struct node
{
char data;
struct node *rchild;
struct node *lchild;
int rtag; // rtag=0时,表示Rchild指向该结点的右孩子;为1时,表示rchild指向该结点的线性后继结点;
int ltag; //Ltag=0时,表示lchild指向该结点的左孩子,为1时,表示Lchild指向该结点的线性前驱结点;
}BiTNode,*BiTree;
void creat(BiTree &T) //递归创建二叉树
{
char ch;
scanf("%c",&ch);
if(ch=='#')
{
T=NULL;
}
else
{
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=ch;
creat(T->lchild);
creat(T->rchild);
}
}
void InOrderTraverse(BiTree T) //递归中序遍历
{
if(T==NULL)
{
return;
}
InOrderTraverse(T->lchild);
printf("%c ",T->data);
InOrderTraverse(T->rchild);
}
BiTree Pre; //全局变量,前驱结点
void InThreading(BiTree &p) //线索化
{
if(p)
{
InThreading(p->lchild); //线索化左子树
if(!p->lchild)
{
p->ltag=1;
p->lchild=Pre; //线索化左孩子,指向前驱
}
if(!Pre->rchild)
{
Pre->rtag=1;
Pre->rchild=p; //线索化右孩子,指向后继
}
Pre=p; //更新前驱结点
InThreading(p->rchild); //线索化右子树
}
}
void InOrderThreading(BiTree &Thrt,BiTree &T) //线索化二叉树,并处理根结点,及最后一个访问结点
{
Thrt->rchild=Thrt; //先指向本身
Thrt->ltag=0;
if(!T)
{
Thrt->lchild=Thrt; //指向自己
return;
}
Pre=Thrt;
Thrt->lchild=T;
InThreading(T);
//处理Thre与最后一个访问结点。
Pre->rchild=Thrt;
Pre->rtag=1;
Thrt->rchild=Pre;
Thrt->rtag=1;
}
int vis(BiTree t)
{
cout<<t->data<<" ";
return 1;
}
int inorder_traverse_thread(BiTree Thrt, int (*visit)(BiTree t)) //线索化后的二叉树中序遍历
{
BiTree p;
p = Thrt->lchild;
while (p != Thrt)
{
while (p->ltag ==0) //找到第一个线索化的左子树
{
p = p->lchild;
}
visit(p);
while (p->rtag == 1 && p->rchild != Thrt) //如果该结点的右孩子是线索,则沿线索找到后继结点
{
p = p->rchild;
visit(p);
}
p = p->rchild; //进入右子树访问
}
return 1;
}
int main()
{
BiTree T;
creat(T);
InOrderTraverse(T);
cout<<endl;
BiTree Thrt;
Thrt=(BiTNode*)malloc(sizeof(BiTNode));
InOrderThreading(Thrt, T);
inorder_traverse_thread(Thrt, vis);
cout<<endl;
return 0;
}