线索二叉树

1. 线索二叉树结构和操作定义

ThreadBinTree.h

//功能:线索标志域所有值
typedef enum{
	SubTree,
	Thread
}NodeFlag;

//功能:线索二叉树结构体
typedef struct ThreadTree{
	DATA data;
	NodeFlag lflag;
	NodeFlag rflag;
	struct ThreadTree *left;
	struct ThreadTree *right;
}ThreadBinTree;

//前驱节点指针
ThreadBinTree *Previous=NULL;

/*---------------------线索二叉树所有操作原型声明 start ------------------------*/
//功能:初始化二叉树
ThreadBinTree *BinTreeInit();
//功能:添加节点到二叉树
void AddNode(ThreadBinTree *bt);
int BinTreeAddNode(ThreadBinTree *bt, ThreadBinTree *node, int n);
//功能:二叉树线索化
//1)先序线索化
//2)中序线索化
void BinTreeThreading_LDR(ThreadBinTree *bt);
//3)后序线索化
//功能:求指定节点的后继
ThreadBinTree *BinTreeNext_LDR(ThreadBinTree *bt);
//功能:求指定节点的前驱
ThreadBinTree *BinTreePrevious_LDR(ThreadBinTree *bt);
//功能:遍历线索二叉树(根据后继指针)
void ThreadBinTree_LDR(ThreadBinTree *bt, void (*oper)(ThreadBinTree *p));
//功能:查找指定数据的节点
ThreadBinTree *BinTreeFind(ThreadBinTree *bt, DATA data);
/*---------------------线索二叉树所有操作原型声明 end --------------------------*/

/*---------------------线索二叉树所有操作具体实现 start ------------------------*/
//功能:初始化二叉树
ThreadBinTree *BinTreeInit(){
	ThreadBinTree *root;
	if(root=(ThreadBinTree *)malloc(sizeof(ThreadBinTree))){
		printf("请输入根节点数据:");
		fflush(stdin);
		scanf("%s", &root->data);
		root->left = NULL;
		root->right = NULL;
		return root;
	}
	return NULL;
}
//功能:添加节点到二叉树
void AddNode(ThreadBinTree *bt){
	ThreadBinTree *node, *parent;
	DATA data;
	int select;

	if(node=(ThreadBinTree *)malloc(sizeof(ThreadBinTree))){
		printf("请输入新节点数据:");
		fflush(stdin);
		scanf("%s", &node->data);
		node->left = NULL;
		node->right = NULL;
		printf("请输入父节点数据:");
		fflush(stdin);
		scanf("%c", &data);
		parent = BinTreeFind(bt, data);
		if(parent == NULL){
			printf("未找到父节点!!");
			free(node);
			return;
		}
		do{
			printf("请选择:1.添加到左子树  2.添加到右子树\n");
			fflush(stdin);
			scanf("%d", &select);
			if(select==1 || select==2)
				BinTreeAddNode(parent, node, select);
		}while(select!=1 && select!=2);
	}
	return ;
}
int BinTreeAddNode(ThreadBinTree *bt, ThreadBinTree *node, int n){
	if(bt==NULL){
		printf("父节点不存在,请先设置父节点!!");
		return 0;
	}
	switch(n){
		case 1:
			if(bt->left){
				printf("左子树节点不为空!");
				return 0;
			}
			else
				bt->left = node;
			break;
		case 2:		//添加到右节点
			if(bt->right){
				printf("右子树节点不为空!");
				return 0;
			}
			else
				bt->right = node;
			break;
		default:
			printf("参数错误!");
			return 0;
	}
	return 1;
}

//功能:二叉树中查找数据
ThreadBinTree *BinTreeFind(ThreadBinTree *bt, DATA data){
	ThreadBinTree *tmp;
	if(bt==NULL)
		return NULL;
	else{
		if(bt->data == data)
			return bt;
		else{
			if(tmp=BinTreeFind(bt->left, data))
				return tmp;
			else if(tmp=BinTreeFind(bt->right, data))
				return tmp;
			else
				return NULL;
		}
	}
}

//功能:二叉树线索化
//1)先序线索化
//2)中序线索化
void BinTreeThreading_LDR(ThreadBinTree *bt){
	if(bt){
		BinTreeThreading_LDR(bt->left);
		bt->lflag = (bt->left)?SubTree:Thread;
		bt->rflag = (bt->right)?SubTree:Thread;
		if(Previous){							//若当前节点的前驱(Previous)存在
			if(Previous->rflag == Thread)
				Previous->right = bt;
			if(bt->lflag == Thread)
				bt->left = Previous;
		}
		Previous = bt;
		BinTreeThreading_LDR(bt->right);
	}	
}
//3)后序线索化

//功能:求指定节点的后继
ThreadBinTree *BinTreeNext_LDR(ThreadBinTree *bt){
	ThreadBinTree *nextnode;
	if(bt==NULL){
		printf("该节点不存在,请重新输入!!");
		return NULL;
	}
	if(bt->rflag == Thread)	//节点bt的右子树为空
		return bt->right;
	else{					//节点bt的右子树不为空
		nextnode = bt->right;
		while(nextnode->lflag == SubTree)
			nextnode = nextnode->left;
		return nextnode;
	}
}
//功能:求指定节点的前驱
ThreadBinTree *BinTreePrevious_LDR(ThreadBinTree *bt){
	ThreadBinTree *nextnode;
	if(bt==NULL){
		printf("二叉线索树为空,请先建立二叉线索树!!");
		return NULL;
	}
	if(bt->lflag == Thread)
		return bt->left;
	else{
		nextnode = bt->left;
		while(nextnode->rflag == SubTree)
			nextnode = nextnode->right;
		return nextnode;
	}
}
//功能:遍历线索二叉树(根据后继指针)
void ThreadBinTree_LDR(ThreadBinTree *bt, void (*oper)(ThreadBinTree *p)){
	if(bt){
		while(bt->lflag == SubTree)		//查找中序遍历的第一个节点
		bt = bt->left;
		do{
			oper(bt);
			bt = BinTreeNext_LDR(bt);		//找中序的后继节点
		}while(bt);
	}
	return;
}


//功能:线索二叉树中查找数据(注意不能用二叉树查找函数代替)
ThreadBinTree *BinTreeSearch(ThreadBinTree *bt, DATA data){
	ThreadBinTree *tmp;
	tmp = bt;
	if(tmp){
		while(tmp->lflag == SubTree)
			tmp = tmp->left;
		while(tmp && tmp->data != data)
			tmp = BinTreeNext_LDR(tmp);		//调用查找后继函数
	}
	return tmp;
}
/*---------------------线索二叉树所有操作具体实现 start ------------------------*/

2. 2.线索二叉树操作测试

ThreadBinTreeTest.cpp

#include<stdlib.h>
#include<stdio.h>

typedef char DATA;

#include"ThreadBinTree.h"

//功能:操作二叉树的函数
void oper(ThreadBinTree *tmp){
	printf("%c ", tmp->data);			//切记%c不能用%s代替,否则会提示错误
	return;
}

int main(){
	int select;
	ThreadBinTree *Root, *previous, *next, *node, *child;
	DATA data;
	do{
		printf("\n---------------------------\n");
		printf("1.初始化二叉树                 2.添加节点到二叉树中\n");
		printf("3.中序线索化二叉树             4.查找指定节点的后继节点\n");
		printf("5.查找指定节点的前驱节点       6.遍历线索二叉树(根据后继指针,可从任何节点开始)\n");
		printf("0.退出\n");
		printf("请选择执行的操作序号:");
		fflush(stdin);
		scanf("%d", &select);
		switch(select){
			case 1:
				Root = BinTreeInit();
				break;
			case 2:
				AddNode(Root);
				break;
			case 3:
				if(Root==NULL)
					printf("二叉树为空,请先建立二叉树!!");
				else
					BinTreeThreading_LDR(Root);
				break;
			case 4:
				printf("请输入要查找的节点数据:");
				fflush(stdin);
				scanf("%c", &data);
				node = BinTreeSearch(Root, data);
				if(node){
					child = BinTreeNext_LDR(node);
					if(child)
						printf("节点%c的后继节点为:%c\n", node->data, child->data);
					else
						printf("节点%c不存在后继节点!\n", node->data);	
				}
				else
					printf("要查找的节点%c不存在,请重新输入!\n", node->data);	
				break;
			case 5:
				printf("请输入要查找的节点数据:");
				fflush(stdin);
				scanf("%c", &data);
				node = BinTreeSearch(Root, data);
				if(node){
					child = BinTreePrevious_LDR(node);
					if(child)
						printf("节点%c的前驱节点为:%c\n", node->data, child->data);
					else
						printf("节点%c不存在前驱节点!\n", node->data);	
				}
				else
					printf("要查找的节点%c不存在,请重新输入!\n", node->data);	
				break;
			case 6:
				//printf("请输入从哪个节点开始遍历:");
				//fflush(stdin);
				//scanf("%c", &data);
				//node = BinTreeSearch(Root, data);
				ThreadBinTree_LDR(Root, oper);
				break;
		}
	}while(select != 0);
	system("pause");
	return 1;
}


你可能感兴趣的:(线索二叉数)