线索二叉树(C语言实现)——中序线索链表

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef char DataType;

//	标志域利用枚举常量来实现 
typedef enum
{
	Link,		//	Link(0)—指针
	Thread		//	Thread(1)—线索 
}flag;

typedef struct TNode
{
	DataType data;			//	数据域 
	struct TNode * lchild;	//	左指针域 
	struct TNode * rchild;	//	右指针域
	flag ltag,rtag;			//	flag == 0——指向左、右孩子,flag == 1——指向前驱、后继           
                         
	
}ThreadTNode,*ThreadBiTree;

void Creat_BiTree(ThreadBiTree * T);						// 建立二叉树 
void Creat_InThreadBiTree(ThreadBiTree * T);				// 建立中序线索二叉树 
void InThread_BiTree(ThreadBiTree * T, ThreadBiTree * pre);	// 中序遍历线索化二叉树 
ThreadBiTree Get_First(ThreadBiTree T);						// 获取线索二叉树中的第一个结点
ThreadBiTree Get_Next(ThreadBiTree T);						// 获取线索二叉树的后继结点 
void InTraverse_ThreadBiTree(ThreadBiTree T);				// 中序遍历线索二叉树 
bool Destroy_InThreadBiTree(ThreadBiTree T);				// 销毁线索二叉树 


int main()
{
	ThreadBiTree T;
	printf("请输入根结点:");
	Creat_BiTree(&T);
	Creat_InThreadBiTree(&T);
	printf("\n");
	printf("中序遍历输出线索二叉树:");
	InTraverse_ThreadBiTree(T);
	printf("\n");
	if(Destroy_InThreadBiTree(T))
		printf("销毁成功!\n");
	else
		printf("销毁失败!\n");

	return 0;
}

void Creat_BiTree(ThreadBiTree * T)
{
	char ch;
	fflush(stdin);
	scanf("%c",&ch);
	if(ch == '#')
	{
		*T = NULL;
		return;
	}
	else
	{
		*T = (ThreadBiTree)malloc(sizeof(ThreadTNode));
		(*T)->data = ch;
		printf("请输入%c的左孩子:",ch);
		Creat_BiTree(&(*T)->lchild);
		printf("请输入%c的右孩子:",ch);
		Creat_BiTree(&(*T)->rchild);
	}
}

void Creat_InThreadBiTree(ThreadBiTree * T)
{
	ThreadBiTree pre = NULL;
	
	if(!(*T))
		return;
	else
	{
		InThread_BiTree(T, &pre);
		pre->rtag = 1;
		pre->rchild = NULL;
		return;
	}	 
} 

void InThread_BiTree(ThreadBiTree * T, ThreadBiTree * pre)
{
	if(!(*T))
		return;
		
	InThread_BiTree(&(*T)->lchild, pre);	//	递归线索化左子树 
	if((*T)->lchild == NULL)
	{
		(*T)->ltag = Thread;
		(*T)->lchild = *pre;
	}
	if((*pre) != NULL && (*pre)->rchild == NULL )// 注意这两玩意的顺序哈 (不然会短路或 
                                                 // 者断路) —前趋指针不为空才有右孩子 
	{
		(*pre)->rtag = Thread;
		(*pre)->rchild = *T;
	}	
	*pre = *T;							//	更新指向前趋结点的指针 
	InThread_BiTree(&(*T)->rchild, pre);//	递归线索化右子树 
}

ThreadBiTree Get_First(ThreadBiTree T)
{
	if(!T)
		return NULL;
	else
	{
		while(T->ltag == Link)	 //	中序遍历:如果左标志域为0,表明该结点存在左孩子,则一直遍 
                                 // 历到最左边的左孩子结点(直到左标志域为1) 
			T = T->lchild;
		
		return T;				// 当且仅当左标志域为1时,表明该结点为子树的最左边结点,同时 
                                // 也是线索二叉树的第一个结点 
	}
} 

ThreadBiTree Get_Next(ThreadBiTree T)	//	寻找下一个结点 
{
	if(!T)
		return NULL;
	else
	{
		if(T->rtag == Thread)			//	如果右标志域为1,表明该结点无右孩子,则直接返回 
                                        //  该结点的后继结点 
		{
			return T->rchild;	
		} 
		else					
			return Get_First(T->rchild);//	如果右标志域为0,说明该结点存在右孩子,这时调用    
                                        // Get_First()函数获取右孩子所在子树的第一个结点 
	}
}

void InTraverse_ThreadBiTree(ThreadBiTree T)
{	
	ThreadBiTree p = Get_First(T);	//	获取中序线索二叉树的第一个结点 
	while(p)
	{
		printf("%3c",p->data);		//	中序遍历输出中序线索二叉树 
		p = Get_Next(p);			//	寻找该结点的下一个结点 
	} 
	
	return;
}

bool Destroy_InThreadBiTree(ThreadBiTree T)
{
	ThreadBiTree p = Get_First(T);
	while(p)
	{
		ThreadBiTree q = Get_Next(p);
		free(p);
		p = q;
	}
	
	T = p = NULL;
	return true;
}

猜你喜欢

转载自blog.csdn.net/Mr_Morgans/article/details/121127114