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;
}