遍历二叉树的过程实际上是以一定的规则将二叉树中的结点排成一个线性序列,是将非线性结构进行线性化操作,使得每一个结点(除了第一个结点和最后一个)在这写线性序列中有且仅有一个前驱和后继。我们已经由二叉树的性质知道:在有n个结点的二叉链表中必定含有n+1个空链域。其思想就是利用这写空链域来存储前驱和后继信息。试作如下规定:若结点有左子树,则其lchild指向其左孩子,否则令lchild指向其前驱;若结点有右子树,则其rchild指向其右子树,否则令rchild指向其后继。为此,在树的结点中增加两个标志域:LTag,RTag; LTag=0 lichild指向其左子树,LTag=1 lichild指向其前驱,RTag=0 lichild指向其右子树,LTag=1 lichild指向其后继。
其线索化和线索化后的遍历操作如下:
//二叉树的线索存储表示和线索化
enum PointerTag {Link,Thread}; //Link==0:指针,Thread=1:线索
typedef struct BiThrNode{
TElemType data;
struct BiThrNode *lchild,*rchild; //左右孩子指针
PointerTag LTag,RTag; //左右标志
BiThrNode(){
data=0;
lchild=NULL;
rchild=NULL;
LTag=Link;
RTag=Link;
}
}BiThrNode,*BiThrTree;
//按照先序创建以二叉线索为存储结构的二叉树
Status CreateBiThrTree(BiThrTree &T){
TElemType ch;
cin>>ch;
if(ch=='@') T=NULL;
else{
if(!(T=(BiThrNode*)malloc(sizeof(BiThrNode)))) return ERROR;
T->data=ch;
T->LTag=Link;
T->RTag=Link;
CreateBiThrTree(T->lchild);
CreateBiThrTree(T->rchild);
}
return OK;
}
BiThrNode *pre=NULL;
void InThreading(BiThrTree p){
if(p){
InThreading(p->lchild); //左子树线索化
if(!p->lchild){
p->LTag=Thread;
p->lchild=pre;
}
if(!pre->rchild){
pre->RTag=Thread;
pre->rchild=p;
}
pre=p;
InThreading(p->rchild);
}
}
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Status InOrderThreading(BiThrTree &Thrt,BiThrTree T){
if(!(Thrt=(BiThrNode*)malloc(sizeof(BiThrNode)))) exit(OVERFLOW);
Thrt->LTag=Link; Thrt->RTag=Thread; //建立头结点
Thrt->rchild=Thrt; //右指针回指
if(!T) Thrt->lchild=Thrt; //如果树为空,左指针回指
else{
Thrt->lchild=T;
pre=Thrt;
InThreading(T);
pre->rchild=Thrt;
pre->RTag=Thread; //最后一个结点线索化
Thrt->rchild=pre;
}
return OK;
}
//对以双向链表为存储结构的二叉树进行遍历
Status InOrderTraverse_Thr(BiThrTree T,Status (*Visit)(TElemType e)){
BiThrNode *p=NULL;
p=T->lchild; //p指向根结点
while(p!=T){ //空树或者遍历结束
while(p->LTag==Link) p=p->lchild;
if(!Visit(p->data)) return ERROR;
while(p->RTag==Thread&&p->rchild!=T){
p=p->rchild;
Visit(p->data);
}
p=p->rchild;
}
return OK;
}
Status PrintData(TElemType e){
cout<<e<<" ";
return OK;
}
int main()
{
BiThrTree thrt,t;
CreateBiThrTree(t);
InOrderThreading(thrt,t);
InOrderTraverse_Thr(thrt,PrintData);
return 0;
}