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