二叉搜索树(C语言)
来源:互联网 发布:网络flash插件未安装 编辑:程序博客网 时间:2024/05/29 16:14
二叉搜索树讲解
学习二叉搜索树的过程中,对于删除操作中的两个节点都存在的情况进行代码编写时,出现了疑惑,所以我着重讲解一下删除操作代码。
首先进行数据的声明:
#include<stdio.h>#include<stdlib.h>typedef int data_type; //声明元素类型typedef struct bst_node{ //node节点值 data_type data; struct bst_node *lchild,*rchild;}bst_t,*bst_p;
第一个函数是查找要插入的节点位置:
传入根节点root与进行比较的值data
bst_p position_insert(bst_p *root,data_type key) //找到要插入的值的位置{ bsp_p s,p = *root; while(p) { s = p; if(p->data == key) //如果这个值本身就存在,返回NULL return NULL; p = (key < p->data) ? p->lchild : p->rchild; //继续向下查找位置 } return s;}
第二个函数与第一个函数搭配使用,即插入操作:
bst_p insert_node(bst_p *root, data_type data) //进行插入操作{ bst_p s,p = *root; s = malloc(sizeof(struct bst_p)); //申请一个bst_p的空间 s->data = data; //把这个传入的值放进这个新申请的空间里面 s->lchild = s->rchild = NULL; if(*root==NULL) //如果是一个空树 *root = s; else { s = position_insert(*root,data); if(s==NULL) //如果要插入的值本身存在 { printf("the element %d exists!\n",data); free(s); return; } }}
第三个函数是查找操作,查找data是否在二叉树中,如果一个树的高度为h,那么查找的时间复杂度最高就是O(h),
bst_p search_node( bst_p *root, data_type data ) //查询数值是否在树中{ bst_p s; s = *root; if(s == NULL) printf("empty tree!\n"); while(s) { if(s->data == data) return s; else if(s->data >data) s = s->rchild; else s = s->lchild; } return NULL;}
第四个函数是删除操作:
首先我放一下完整的代码,稍后说明我的理解:
删除操作主要分为三种,
(1)第一种是删除的是子节点
(2)第二种是删除的节点左右子节点其中有一个存在
(3)第三种是左右两个节点都存在
bool delete_node(bst_p *root,data_type data) //声明一个q节点,q节点是p节点的父节点{ bst_p q = NULL , p = *root; bool sign = false; if(p ==NULL){ //判断是否是空树 printf("empty tree !\n nothing to delete"); return true; } while(p && !sign) //寻找该节点 { if(p->data == data) sign = true; else if(p->data > data) { q = p; p = p->rchild; } else { q = p; p = p->lchild; } } if(sign == false){ //没找到该节点 printf("element don't exists!\n"); return true; } if( p->lchild == NULL && p->rchild == NULL ) //两个子节点都为空,直接删除 { if(p == root) printf("now root is delete!\n"); free(s); return true; } else if( !p->rchild || !p->lchild ) //其中一个子节点为空 { if( q->lchild == p && p->rchild ) { q->lchild = p->rchild; free(p); return true; } else if(q->rchild == p && p->rchild) { q->rchild = p->rchild; free(p); return true; } else if(q->lchild == p && p->lchild) { q->lchild = p->lchild; free(p); return true; } else if(q->rchild ==p && p->lchild) { q->rchild = p->lchild; free(p); return true; } } else//两个字节点都不为空 { bst_p s,t = p;//采用前驱方式 s = p->lchild; while(s->rchild) { t = s; s = s->rchild; } p->data = s->data; //节点s的值赋给节点p的值 if(t == p) { p->lchild = s->lchild; } else { t->rchild = s->lchild; } free(s); free(t); return true; }}
这段代码主要说的是查找要删除的节点,并保留节点p的父节点,保留父节点主要是考虑到第三种情况,再删除节点时需要用到父节点进行赋值
while(p && !sign) //寻找该节点 { if(p->data == data) sign = true; else if(p->data > data) { q = p; p = p->rchild; } else { q = p; p = p->lchild; } }
(1)删除子节点
if( p->lchild == NULL && p->rchild == NULL ) //两个子节点都为空,直接删除 { if(p == root) printf("now root is delete!\n"); free(s); return true; }
(2)删除节点中子节点有一个存在
1.这里用到了父节点q,我们在进行删除时,当p是q的左孩子,并且p有右孩子时
else if( !p->rchild || !p->lchild ) //其中一个子节点为空 { if( q->lchild == p && p->rchild ) { q->lchild = p->rchild; free(p); return true; }2.当p是q的右孩子,并且p有右孩子时,
else if(q->rchild == p && p->rchild) { q->rchild = p->rchild; free(p); return true; }3.当p是q的左孩子,并且p有左孩子时,
else if(q->lchild == p && p->lchild) { q->lchild = p->lchild; free(p); return true; }4.当p是q的右孩子,并且p有左孩子时,else if(q->rchild ==p && p->lchild) { q->rchild = p->lchild; free(p); return true; } }(3)当删除的节点有左右两个子节点时,
else//两个字节点都不为空 { bst_p s,t = p;//采用前驱方式 s = p->lchild; while(s->rchild) { t = s; s = s->rchild; } p->data = s->data; //节点s的值赋给节点p的值 if(t == p) p->lchild = s->lchild; else t->rchild = s->lchild; free(s); free(t); return true; }
阅读全文
0 0
- 二叉搜索树(C语言)
- C语言二叉搜索树
- 题目1009:二叉搜索树(C语言实现)
- 二叉搜索树 c 语言实现
- C语言二叉搜索树基本操作
- 二叉搜索树 C语言实现
- 二叉搜索树(BST) ----- C语言
- c语言实现:二叉搜索树
- c语言二叉树和二叉搜索树的实现
- 二叉搜索树(C++)
- 二叉搜索树实现文件C语言(BinarySearchTree.c)
- 二叉搜索树(c++)
- C语言二叉树实现及搜索算法
- 二叉搜索树头文件C语言(BinarySearchTree.h)
- 二叉搜索树最低访问代价问题C语言
- 算法导论C语言实现: 二叉搜索树(binary tree)
- C语言(二叉树)
- 二叉树(C语言)
- 回到顶部
- Jmeter数据库请求配置
- jQuery对象和dom对象的区别和相互转换
- zookeeper
- 关于Context的研究
- 二叉搜索树(C语言)
- 反射
- POJ 2976 Dropping tests 【二分:最大化平均值】
- Map.Entry类
- ubuntu下文件的压缩&解压缩
- 数据库概念和操作数据库的命令
- SpringBoot启用log4j日志
- day04-超级猜图
- EC2部署IIS网站