二叉树的中序线索化

来源:互联网 发布:csgo淘宝黄金版 编辑:程序博客网 时间:2024/06/07 03:26

注释有什么地方搞错了 欢迎大佬们指出!谢谢了!数据结构书上的二叉树的中序线索化 !

#include<malloc.h>

#include<stdio.h>
typedef char ElemType;
typedef enum{ Link,Thread} PointerTag;//枚举类型
//线索存储标志位 Link==0是指向左右孩子的指针,thread==1是前驱后驱的线索
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
PointerTag Ltag;     //标识域 Ltag=0,指示结点的左孩子,Ltag=1指示结点的前驱
PointerTag Rtag;     //标识域 Rtag=0,指示结点的右孩子,Rtag=1指示结点的后继
}BiTNode,*BiTree;
           //全局变量,始终指向刚刚访问过的结点
BiTNode *pre;




void CreateTree(BiTree &T)  //先序递归创建二叉树
{
char  ch;
scanf("%c",&ch);
if(ch=='#') T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiTNode));
T->data=ch;
  T->Ltag=Link;  //表示要指向结点的左孩子
  T->Rtag=Link;  //表示要指向结点的右孩子
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}


void inThreading(BiTree &BT)
{
if(BT){
inThreading(BT->lchild);//递归左孩子线索化
//结点处理
if(!BT->lchild)//前驱线索,如果这个结点没有左孩子
{
BT->Ltag=Thread; //Ltag为1,表示空链域存放结点的前驱
BT->lchild=pre;  //将BT指向左孩子的指针指向刚刚访问过的结点
}
if(!pre->rchild)//后继线索,如果这个结点没有右孩子
{
          pre->Rtag=Thread;  //Rtag为1,表示空连域要放结点的后驱
 pre->rchild=BT;    //将BT指向右孩子的指针域,存它自己
}
pre=BT;               //访问完成,这个结点线索化完成,然后继续循环
inThreading(BT->rchild);//递归右孩子线索化
}
}


void inorderThreading(BiTree &p,BiTree &T)
{     //p结点为头指针,T为树根结点


p=(BiTree)malloc(sizeof(BiTNode));//创建一个头结点
p->Ltag=Link;                    
p->Rtag=Thread;
p->rchild=p;      //有指针回指
if(!T)  p->lchild=p;   //若二叉树为空,则指针回指
else
{
p->lchild=T;       //若二叉树不为空,lchild指向根指针
pre=p;            
inThreading(T);       //中序遍历进行中序线索化
//最后一个结点线索化
pre->Rtag=Thread;
pre->rchild=p;       //终端指针指向头结点
p->rchild=pre;       //头结点的右指针指向终端结点
}
}






void  inorderTraverse_Iter(BiTree T)
{  //中序遍历二叉树,非递归实现
BiTree p;
p=T->lchild; //p指向根节点T
while(p!=T)     //二叉树非空或遍历未结束
{
while(p->Ltag==Link)  //访问左子树为空的结点
{
p=p->lchild;
}
printf("%c",p->data);
while((p->Rtag==Thread)&&(p->rchild!=T)) //p的rchild指向后继,访问p结点的后继
{
p=p->rchild;
printf("%c",p->data);
}
p=p->rchild;//p的rchild指向右孩子
}
}








int main()
{
    BiTree  T;
BiTree  BT;
printf("按照先序递归遍历创建二叉树:\n");
CreateTree(T);                                      //尝试输入  ABC###DE###         就是这个 A(B(C),D(E))
printf("完成中序线索化!\n");
inorderThreading(BT,T);
printf("中序线索化输出:\n");
inorderTraverse_Iter(BT);
return 0;
}