为了节省空间,将空节点指向它们的前驱后继,我们在遍历时遇到空节点可以标记起来,不然你就不知道它所指的到底是他的孩子还是前驱或者后继
尤其注意后继,由于我们还没有访问到后继,只能对前驱节点做判断再指向后继
#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
char data;
node *l,*r;
bool Ltag,Rtag;
}*tree;
void creat(node *T)//前序建树
{
char c;
cin >> c;
if(c!='#')
{
T=new node;
T->data=c;
creat(T->l);
creat(T->r);
}
else T=NULL;
}
void InThreading(node *p,node *pre)
{
if(p)
{
InThreading(p->l,pre);
if(!p->l)//没有左孩子
{
p->Ltag=true;//修改标志域为前驱
p->l=pre;//左孩子指向前驱
}
if(!pre->r)//没有右孩子
{
pre->Rtag=true;//修改标志域为后继
pre->r=p;//前驱孩子指向当前节点
}
pre=p;//保持pre指向p的前驱
InThreading(p->r,pre);
}
}
int InorderTraverse(node *T)
{
node *p;
p=T->l;
while(p!=T)
{
while(p->Ltag==false)//走向左子树的尽头
p=p->l;
cout << p->data;
while(p->Rtag==true&&p->r!=T)
{
p=p->r;//访问该节点的后继节点
cout << p->data;
}
p=p->r;
}
return 1;
}
int main()
{
node * T,*B;
creat(T);
pre=T;
InThreading(B,T);
InorderTraverse(B);
}