#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef enum PointerTag {Link,Thread};
typedef int Status;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
enum PointerTag LTag,RTag;
}BiTNode,*BiTree;
int CreateBiTree(BiTree *T);
Status Visit(char e);
Status PreOrderThreadTraverse(BiTree T);
Status PreOrderThreadBackTraverse(BiTree T);
Status PreOrderThreading(BiTree Thrt,BiTree T);
void PreThreading(BiTree p,BiTree *pre);
Status PreOrderTraverse(BiTree T);
int main()
{
BiTree *T,Thrt;
T=(BiTree*)malloc(sizeof(BiTree));
Thrt=(BiTree)malloc(sizeof(BiTNode));
CreateBiTree(T);
printf("\n前序遍历结果:");
PreOrderTraverse(*T);
PreOrderThreading(Thrt,*T);
printf("\n线索化后前序正向遍历结果:");
PreOrderThreadTraverse(Thrt);
return 0;
}
int CreateBiTree(BiTree *T)
{
fflush(stdin);
printf("please input the node data:");
char ch;
scanf("%c",&ch);
BiTree p;
p=(BiTree)malloc(sizeof(BiTNode));
p->data=ch;
*T=p;
char c;
fflush(stdin);
printf("Dose %c has left child(y--yes,n--no):",ch);
scanf("%c",&c);
if(c=='y')
CreateBiTree(&(*T)->lchild);
else
(*T)->lchild=NULL;
fflush(stdin);
printf("Dose %c has right child(y--yes,n--no):",ch);
scanf("%c",&c);
if(c=='y')
CreateBiTree(&(*T)->rchild);
else
(*T)->rchild=NULL;
return 0;
}
Status Visit(char e)
{
printf("%c ",e);
return OK;
}
//按线索遍历线索二叉树:从第一个结点起顺后继进行遍历
Status PreOrderThreadTraverse(BiTree T)
{
BiTree p;
p=(BiTree)malloc(sizeof(BiTNode));
p=T->lchild; //从表头结点的左子树开始,即根结点;
while(p!=T) //如果表头结点的左子树指向自己,则为空树;
{
while(p->LTag==Link)
{
Visit(p->data);
p=p->lchild; //如果左标志为链接,则跳过不遍历,顺着链接往左传递,直到左标志为线索,才是第一个结点;
}
Visit(p->data);
while(p->RTag==Thread && p->rchild!=T)
{
//只要右标志为线索,则顺着线索遍历,直到指向表头或者右标志为链接;
p=p->rchild;
Visit(p->data);
}
p=p->rchild; //当右标志为链接时,跳过不遍历,顺着链接走;
}
return OK;
}
//前序线索化二叉树
Status PreOrderThreading(BiTree Thrt,BiTree T)
{
Thrt->LTag=Link; //表头结点左标志为链接,左指针指向根结点;
Thrt->RTag=Thread; //表头结点右标志为线索,右指针应指向后继,当前为自己;
Thrt->rchild=Thrt;
if(!T)
Thrt->lchild=Thrt; //如果二叉树为空,则左指针回转,指向自己;
else
{
BiTree pre;
pre=(BiTree)malloc(sizeof(BiTNode)); //用于保留前一结点
Thrt->lchild=T; //表头结点左指针指向根结点;
pre=Thrt; //表头结点成为前一结点;
PreThreading(T,&pre); //线索化当前结点;
pre->rchild=Thrt; //pre指向的前一结点为树中的最后一个结点,右指针应指向表头结点;
pre->RTag=Thread;
Thrt->rchild=pre; //表头结点的右指针指向树的最后一个结点;
}
return OK;
}
//对单一结点线索化
void PreThreading(BiTree p,BiTree *pre)
{
if(p)
{
//如果左子树为空,则左标志为线索,左指针指向前驱
if(!p->lchild)
{
p->LTag=Thread;
p->lchild=*pre;
}
else
p->LTag=Link; //如果左子树非空,则只需要改变左标志为链接,左指针不变;
//如果前一节点的右子树为空,则其右标志为线索,右指针指向后继,即当前结点;
if(!(*pre)->rchild)
{
(*pre)->RTag=Thread;
(*pre)->rchild=p;
}
else
(*pre)->RTag=Link; //如果右子树非空,则只需要改变右标志为链接,右指针不变;
*pre=p; //将当前结点定义为前继结点,用于右子树的线索化;
if(p->LTag==Link)
PreThreading(p->lchild,pre);
if(p->RTag==Link)
PreThreading(p->rchild,pre);
}
}
Status PreOrderTraverse(BiTree T)
{
if(T)
{
if(Visit(T->data))
if(PreOrderTraverse(T->lchild))
if(PreOrderTraverse(T->rchild))
return OK;
return ERROR;
}
else
return OK;
}
来源:https://blog.csdn.net/weixin_43213382/article/details/98859381