二叉排序树的一些简单操作

来源:互联网 发布:网络被攻击 编辑:程序博客网 时间:2024/05/21 22:30

二叉排序树就是左孩子比根节点小,右孩子比根节点大,左小右大的那种二叉树。从定义来看,二叉排序树是不可能有俩个数是相同的。

二叉排序树是为了查找时更加有效率,查找的时候如果小,就往左边跑,一下子就去掉了整个右边。

#include <stdio.h>#include <stdlib.h>#include <malloc.h>typedef float datatype;typedef struct BiTNode {datatype data;struct BiTNode *lchild, *rchild;}BiTNode,*BiTree;//===================================================//中序遍历void MidTraverse(BiTree tree) {if(tree) {MidTraverse(tree->lchild);printf("%.1f ",tree->data);//修改数据类型的时候这里也要改MidTraverse(tree->rchild);}//if}//MidTraverse//=======================================================//找数值是否已经在排序树中了/*这是在网上看到的递归写法,parent代表要找节点的父节点,*find返回要找节点*/bool SearchBST(BiTree tree, datatype item, BiTree *parent, BiTree *find) {if(!tree) {//空树*find = *parent;return false ;}//ifelse if(item == tree->data) {*find = tree;//找到了节点return true;}//else ifelse if(item < tree->data) {//找左子树return SearchBST(tree->lchild, item, &tree, find);}//else ifelse //找右子树return SearchBST(tree->rchild, item, &tree, find);}//SearchBST //================================================================//上面函数非递归法/*传指针是因为后面的插入删除都要用到parent find的返回值如果找到了find就是要找的节点,否则为空找到了parent就是find的父节点,否则parent就是叶子节点。*/bool SearchBST1(BiTree tree, datatype item, BiTree *parent, BiTree *find) {*find = tree;//开始当然从根节点开始while( (*find) && item != (*find)->data) {*parent = *find;//parent作为find的父节点//不要写成parent= find虽然语法上没错,但逻辑上不对if(item < (*find)->data) //找左孩子*find = (*find)->lchild ;else//找右孩子*find = (*find)->rchild;}//whileif(!(*find)) {printf("没找到\n");return false;}elsereturn true;}//SearchBST1//=============================================================//二叉排序树中插入节点/*插入一个数之前判断树中是否已经有了(二叉排序树定义就是没有相同的数)插入树的过程就是建立二叉排序树的过程,开始建立树为空,那么第一个插入的数就做根节点,然后接下来插入数,就同样判断是否存在,找到插入数在树中的parent,小点就做parent左孩子,大点就做parent右孩子。原理就酱紫。*/bool InsertBST(BiTree *tree, datatype item) {BiTree p = *tree;BiTree find;BiTree pNew;BiTree parent = NULL ;if(SearchBST1(p, item, &parent, &find)) {printf("该元素已经存在!\n");return false ;}//ifelse {/*在判断条件里创建节点比一进函数就创要好,因为条件不满足就不用浪费空间了,小知识吧,慢慢进步*/printf("进入赋值:");pNew = (BiTree )malloc(sizeof(BiTNode ));pNew->data = item;pNew->lchild = pNew->rchild = NULL;if(!*tree) {*tree = pNew;printf("做根节点\n");}//ifelse if(item < parent->data) {printf("左孩子\n");parent->lchild = pNew;}//else ifelse {printf("右孩子\n");parent->rchild = pNew;}//elseprintf("遍历:\n");MidTraverse (*tree);printf("\n");return true;}//else}//InsertBST//=========================================================//删除节点/*删除节点有三种情况,一种是删除的节点没有左右孩子,光杆司令,第二种是只有一个孩子,这俩种可以归纳为一种方式:if(!find->lchild || !find->rchild)假如要删除的节点a是她父节点的左孩子,那么反正a最多也就只有一个孩子,就相当于这个唯一的孩子把a给挤走了,自己做a父节点的左孩子而第三种接口就是要删除的节点有俩个孩子,假如我们我删除节点3,这时候解决的关键是谁来顶替3,如果做的多的话就可以知道,我们要找的其实是按中序遍历(左中右)的直接前驱,也就是3.5。                            6                           / \                          3   7                         / \   \                        2   4   10                       /   / \   /                      1   3.6 5  8                           /      \                        3.5        9                         \                         3.7                           \                           3.8*/bool DeleteBST(BiTree tree, datatype item) {BiTree p = tree;BiTree parent = NULL;BiTree find;if(!SearchBST1(p, item, &parent, &find)) {printf("删除的元素不在树中\n");return false ;}//ifif(!find->lchild || !find->rchild) {//一个或俩者都为空if(parent->lchild == find) parent->lchild = (find->lchild) ? find->lchild : find->rchild;elseparent->rchild = (find->lchild) ? find->lchild : find->rchild;free(find);}//ifelse {//有俩个孩子BiTree temp = find->rchild;//要删除节点的右孩子BiTree p;//直接前驱的父节点while(temp->lchild) {p = temp;//父节点temp = temp->lchild;//直接前驱也就是find的右孩子的最左节点,temp是直接前驱}//whilefind->data = temp->data;//直接前驱的值给要删除节点//前驱肯定没有左孩子的,要不然就不是直接前驱了。if(temp->rchild) {//如果直接前驱有右孩子p->rchild = temp->rchild;//直接前驱的右孩子占据前驱的位置}//iffree(p->lchild);//看,最后释放的却不是要删除的节点空间,变相理解这里删除p->lchild = NULL ;//free(temp);//temp = NULL;//这样子却不对,按道理p->lchild和temp应该一样的,还是我程序写错了?不明白求指教}//else}//DeleteBST//===================================================//测试程序int main() {BiTree tree = NULL;//int a[] = {62,58,88,47,73,99,35,51,93,37};float a[] = {6,3,7,2,4,1,5,3.6,3.5,3.8,3.7,10};for(int i = 0 ; i < 12; i++) {InsertBST(&tree,a[i]);}MidTraverse (tree);printf("\n");DeleteBST(tree,3);MidTraverse (tree);return 0;}



0 0
原创粉丝点击