真的参考了很多 终于明白啦!!
记录一下!
/* 测试main时 要分开测试三种建立线索二叉树的方法
在main函数建二叉树的时候用了三个变量建立三个二叉树 却还是不能同时测试
很迷**/
#include "stdio.h"
#include "stdlib.h"
#define NULL 0
#define OK 1
typedef char TElemType;
typedef int Status;
typedef enum{Link,Thread} PointerTag;
typedef struct BiThrNode{
TElemType data;
struct BiThrNode *lchild,*rchild;
PointerTag LTag,RTag;
}BiThrNode,*BiThrTree;
BiThrTree pre; //pre为全局变量
Status CreateBiTree(BiThrTree *T);
Status PreThreading(BiThrTree t);
Status PreorderThreading(BiThrTree *p, BiThrTree t);
Status PreorderTraverse(BiThrTree p);
Status InThreading(BiThrTree t);
Status InorderThreading(BiThrTree *p, BiThrTree t);
Status InorderTraverse(BiThrTree p);
BiThrTree parent(BiThrTree thrt,BiThrTree p);
Status PostThreading(BiThrTree t);
Status PostorderThreading(BiThrTree *p, BiThrTree t);
Status PostorderTraverse(BiThrTree p);
//先序创建二叉树
Status CreateBiTree(BiThrTree *T){
/*按先序次序输入二叉树中结点的值,#字符表示空树,注意使每个结点的左右标志初始为Link(即为0);*/
char ch;
ch=getchar();
if (ch=='*')
(*T)=NULL;
else{
(*T)=(BiThrTree) malloc(sizeof(BiThrNode));
(*T)->data=ch;
(*T)->LTag=(*T)->RTag=Link;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
return OK;
}
/**********************************************先序****************************/
//先序添加线索
Status PreThreading(BiThrTree t){
if(t){
if(t->lchild==NULL){
t->lchild = pre;
t->LTag = Thread;
}
if(pre && pre->rchild == NULL){
pre->rchild = t;
pre->RTag = Thread;
}
pre = t;
if(t->LTag == Link)
PreThreading(t->lchild);
if(t->RTag == Link)
PreThreading(t->rchild);
}
return OK;
}
//先序遍历二叉树,并将其中序线索化
Status PreorderThreading(BiThrTree *p, BiThrTree t){
(*p) = (BiThrTree)malloc(sizeof(BiThrNode));
(*p)->LTag = Link;
(*p)->RTag = Thread;
(*p)->rchild = (*p);
if(!t){
(*p)->lchild = (*p);
}
else{
(*p)->lchild = t;
pre = (*p);
PreThreading(t);
(*p)->rchild = pre;
pre->RTag = Thread;///现在pre是最后一个节点啦
pre->rchild = (*p);
}
return OK;
}
//先序线索二叉树遍历
Status PreorderTraverse(BiThrTree p){
BiThrTree t;
t = p->lchild;
while(t!=p){
while(t->LTag == Link){
printf("%c ",t->data);
t = t->lchild;
}
printf("%c ",t->data);
while(t->RTag == Thread && t->rchild!=p){
t = t->rchild;
printf("%c ",t->data);
}
t = t->rchild;
}
return OK;
}
/**********************************************中序****************************/
//中序添加线索
Status InThreading(BiThrTree p){
if(p){
InThreading(p->lchild); //p的左子树线索化
if(p->lchild==NULL){ //前驱线索
p->LTag=Thread;
p->lchild=pre;
}
if(pre->rchild==NULL){ //后继线索
pre->RTag=Thread;
pre->rchild=p;
}
pre=p; //保持pre为p的前驱
InThreading(p->rchild); //右子树线索化
}
return OK;
}
//中序遍历建立线索二叉树
Status InorderThreading(BiThrTree *Thrt,BiThrTree T){
//中序遍历二叉树T,并将其中序线索化
(*Thrt)=(BiThrTree)malloc(sizeof(BiThrNode)); //这样写太多了吧
(*Thrt)->LTag=Link;
(*Thrt)->RTag=Thread;(*Thrt)->rchild=(*Thrt);
if(T==NULL)
(*Thrt)->lchild=(*Thrt);
else{
(*Thrt)->lchild=T;pre=(*Thrt);
InThreading(T);
pre->rchild=(*Thrt);
pre->RTag=Thread;
(*Thrt)->rchild=pre;
}
return OK;
}
//中序线索二叉树遍历
Status InorderTraverse(BiThrTree Thrt){
//中序遍历线索二叉树Thrt,Thrt指向头结点
BiThrTree p;
p=Thrt->lchild;
while(p!=Thrt){
while(p->LTag==Link)
p=p->lchild;
printf("%-2c",p->data);
while(p->RTag==Thread &&p->rchild!=Thrt){
p=p->rchild;
printf("%c ",p->data);
}
p=p->rchild;
}
return OK;
}
/**********************************************后序****************************/
//后序添加线索
Status PostThreading(BiThrTree p)
{
if (p){
PostThreading(p->lchild);
PostThreading(p->rchild);
if (p->lchild==NULL){
p->lchild = pre;
p->LTag = Thread;
}
if (pre != NULL&&pre->rchild == NULL){
pre->rchild = p;
pre->RTag = Thread;
}
pre = p;
}
return OK;
}
//后序遍历二叉树,并将其后序线索化
Status PostorderThreading(BiThrTree *H,BiThrTree T) //创建头节点,后序线索二叉树
{
(*H) = (BiThrTree)malloc(sizeof(BiThrNode));
(*H)->rchild = (*H);
(*H)->RTag = Link;
if(!T)
{
(*H)->lchild = (*H);
(*H)->LTag = Link;
}
else
{
pre = (*H);
(*H)->lchild = T;
(*H)->LTag = Link;
PostThreading(T);
(*H)->rchild = pre;
}
return 1;
}
//找双亲
BiThrTree parent(BiThrTree thrt,BiThrTree p)
{
BiThrTree temp;
temp=thrt;
if(temp->lchild==p)
return temp;//父节点是头结点
else
{
temp=temp->lchild;
while( temp->lchild!=p && temp->rchild!=p )
{
if(Link==temp->RTag)
temp=temp->rchild;//结点有右结点,往右
else
temp=temp->lchild;
} //如果结点没有右孩子,去左孩子,没有左孩子,去前驱
}
return temp;
}
//后续线索二叉树遍历
Status PostorderTraverse(BiThrTree Thrt)
{
BiThrTree p;
BiThrTree par;
p=Thrt->lchild;
while(1)
{
while(Link==p->LTag)
p=p->lchild;
if(Link==p->RTag)
p=p->rchild; //p指向第一个被访问的结点
else
break;
}
while(p!=Thrt)
{
printf("%c ",p->data);
par=parent(Thrt,p);//parent是p的双亲:
if(Thrt==par)
p=Thrt;//若parent是thrt,即p是根结点,则无后继
else if(p==par->rchild||Thread==par->RTag)
p=par;//若p是双亲的右孩子,或者是独生左孩子,则后继为双亲
else
{
while(par->RTag==Link)
{ //若p是有兄弟的左孩子,则后继为双亲的右子树上后序遍历访问的第一个节点。
par=par->rchild;
while(par->LTag==Link)
{
par=par->lchild;
}
}
p=par;
}
}
return OK;
}
int main(){
BiThrTree T=NULL,Thrt=NULL;
BiThrTree S=NULL,Thst=NULL;
BiThrTree K=NULL,Thkt=NULL;
/*测试先序线索算法*/
printf("\nCreate a Thread Binary Tree: ");
CreateBiTree(&T); //建立二叉树T
printf("\n二叉树创建完成!\n");
PreorderThreading(&Thrt, T);
printf("\n二叉树先序线索化完成!\n\n");
printf("先序遍历线索二叉树: ");
PreorderTraverse(Thrt); //先序遍历线索二叉树
printf("\n\n先序遍历线索二叉树完成!\n\n");
/*测试中序线索算法*/
printf("\nCreate a Thread Binary Tree: ");
CreateBiTree(&S); //建立二叉树T
printf("\n二叉树创建完成!\n");
InorderThreading(&Thst, S);
printf("\n二叉树中序线索化完成!\n\n");
printf("中序遍历线索二叉树: ");
InorderTraverse(Thst); //中序遍历线索二叉树
printf("\n\n中序遍历线索二叉树完成!\n\n");
/*测试后序线索算法*/
printf("\nCreate a Thread Binary Tree: ");
CreateBiTree(&K); //建立二叉树T
printf("\n二叉树创建完成!\n");
PostorderThreading(&Thkt, K);
printf("\n二叉树后序线索化完成!\n\n");
printf("后序遍历线索二叉树: ");
PostorderTraverse(Thkt); //后序遍历线索二叉树
printf("\n\n后序遍历线索二叉树完成!\n\n");
return OK;
}