C语言手撸搜索(查找)二叉树---创建,插入,删除
C语言搜索(查找)二叉树
- 存储结构
- 函数声明
- 查找函数
- 创建二叉树
- 创建节点
- 创建节点数为n的搜索二叉树
- 二叉树的插入
- 删除操作
存储结构
//元素类型
#define TypeElem inttypedef struct BSTNode {TypeElem data;struct BSTNode * lchild;struct BSTNode* rchild;
}BSTNode,*BSTree;
函数声明
//创建一个节点
BSTNode* Create_Node(TypeElem key);
//创建二叉排序树
void Create_BST(BSTree& T,int n);
//查找值在二叉树中的位置
BSTNode* Search_BST(BSTree T, int val);
//查找该值在二叉树的父节点
BSTNode* Search_Pre_BST(BSTree T, int val);
//插入一个节点
void Insert_BST(BSTree node,int val);
//删除值为val的节点
void Delet_BST(BSTree& T,int val);
//中序递归遍历二叉树的所有节点
void InOrder(BSTree T);
查找函数
算法的基本思路:
- 若二叉排序树为空树,则查找失败。
- 将给定值key与根节点的关键字比较,若相等,则查找成功。
- 将给定值key小于根节点的关键字,则在左子树查找,否则在右子树查找。
代码:
//查找值在二叉树中的位置
BSTNode* Search_BST(BSTree T, int val) {while (T) {if (T->data == val)return T;else if (T->data < val)T = T->rchild;elseT = T->rchild;}
}
创建二叉树
创建节点
//创建一个节点
BSTNode* Create_Node(TypeElem key) {BSTNode* node = (BSTNode*)malloc(sizeof(BSTNode));if (!node) {printf("申请空间失败!\n");return 0;}node->data = key;//左右指针置为空是个好习惯node->lchild = node->rchild = NULL;return node;
}
创建节点数为n的搜索二叉树
//创建含义n个元素的二叉排序树
void Create_BST(BSTree& T, int n) {int x;BSTNode* node;while (n--) {scanf_s("%d", &x);//为空创建根节点,否则插入节点if (!T)T = Create_Node(x);elseInsert_BST(T, x);}
}
二叉树的插入
二叉排序树是一种动态树表,其特点是树的结构通常不是一次生成的,而是在查找过程中,当二叉树查找失败时,才进行插入,并且新插入的结点一定是一个新添加的叶子结点。其插入过程为:若二叉排序树为空,则将新结点作为根结点插入。若二叉排序树非空,则将新结点的关键字与二叉排序树根结点的关键字比较,若与根结点关键字相等,则不插入,若小于根结点的关键字,则插入二叉排序树的左子树,若大于根结点的关键字,则插入二叉排序树的右子树。
代码:
//插入一个节点
void Insert_BST(BSTree T, int val) {if (!T)printf("空\n");BSTree p = T,pre = NULL; //p 是工作指针,pre指向要插入节点的前一个位置// p非空while (p) {pre = p;// 存在该值后就不插入了if (val == p->data)return;else if (val > p->data)p = p->rchild;elsep = p->lchild;}//创建一个值为 val 的节点p = Create_Node(val);//如果比父节点大插入右边if (val > pre->data)pre->rchild = p;elsepre->lchild = p;
}
删除操作
删除操作有以下几种情况:(假设p为删除的节点,f为其父节点)
- 待删除的节点p为叶子结点;
由于删除叶子结点不影响二叉树的特性,所以可以直接删除,即只需要将删除节点的父节点的相应指针域改为空指针即可。
- 要删除的节点p只有左子树或者只有右子树。
只需将左子树的根节点或者右子树的根节点取代要删除节点位置即可。
- 待删除节点的左、右子树均非空。
首先找到节点p在中序序列的直接前驱节点s,然后用s的值替代节点p的值,再将节点s删除。
代码:
//删除值为val的节点
void Delet_BST(BSTree& T,int val) {// 查找该值对应的节点BSTNode* f,*p;p = T;f = NULL;while (p) {if (p->data == val)break;f = p;if (p->data > val)p = p->lchild;elsep = p->rchild;}//如果节点非空if (p) {BSTNode* q, * s;/*情况一:如果左右子树均不为空*/if (p->lchild && p->rchild) {//考虑左子树的根没有左子树的情况q = p;//因为一个节点中序遍历的前驱一定在其左子树s = p->lchild;//同时因为中序遍历顺序为左根右,//根节点相当于其左子树第一个节点的。//而在一个子树中,要想从左跳到根,则必须遍历完其右子树。//所以从 s的右子树找node节点的前驱。while (s->rchild) {// p存的是其前驱的前一个节点q = s;s = s->rchild;}//将node处的值用 其前驱的值代替p->data = s->data;//表明node的左子树的第一个节点存在右子树//则前驱所在节点为其前驱的右子树位置if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;free(s);}/*第二种情况:被删除节点缺右子树,包含左右子树都缺的情况;缺右子树就用左子树去填*/else if (p->rchild == NULL) {//不是根节点/*则有两种情况,* 1是节点位于父节点的左子树,就令父节点的左子树为节点的左子树* 2是节点位于父节点的右子树,就令父节点的右子树为节点的左子树*/if (f) {if (f->lchild == p) {f->lchild = p->lchild;p->lchild = NULL;}else {f->rchild = p->lchild;p->lchild = NULL;}//释放删除掉节点的空间free(p);}//如果是根节点表明根节点的右子树为空,那么只需让其左子树替代其位置else {f = p;p = p->lchild;f->lchild = NULL;free(f);//记得更新更节点T = p;}}/*第三种情况:被删除节点缺左子树,包含左右子树都缺的情况;缺右子树就用右子树去填*///步骤和第二种情况类似就不重复说明了else {if (f) {if (f->lchild == p) {f->lchild = p->rchild;p->rchild = NULL;}else {f->rchild = p->rchild;p->rchild = NULL;}free(p);}else {f = p;p = p->rchild;f->lchild = NULL;free(f);T = p;}}}else {printf("该值不存在!\n");}
}
C语言手撸搜索(查找)二叉树---创建,插入,删除相关推荐
- 用c语言实现单链表的初始化,建表,查找,求长度,插入,删除等操作,【YTU+2430+C语言习题+链表建立+插入+删除+输(5)...
的打印.判断链表是否为空.计算链表长度.插入节点.删除节点.删除整个链表.(2) 线性表adt顺序存储实现中的创建.查找.插入和删除等基本操作及相关算法,线性表adt链式存储实现中单链表.循环链表和双 ...
- 【C++编程语言】之string容器 基本概念 构造函数 赋值 拼接 查找 替换比较 插入 删除 子串获取
目录 1.string基本概念 2.string构造函数 3.string赋值操作 4.string字符串拼接 5.string查找和替换 6.string字符串比较 7.string单个字符的访问和 ...
- c语言用链表对学生成绩排序,学生成绩排序和平均分计算利用c语言链表的创建插入删除.doc...
#define NULL 0 #define LEN sizeof(struct student) struct student { long num; float score; struct stu ...
- BST 递归实现二叉树: 插入 删除 查找
二叉树遍历: 前序遍历: 本身 左子树 右子树 中序遍历: 左子树 本身 右子树 从小到大排列 后续遍历: 左子树 右子树 本身 二叉树前驱: 当前节点左子树最大的节点 二叉树后继: 当前节点右子树最 ...
- 二叉搜索树(创建,插入,删除):基础篇,适合新手观看。
1.1 二叉搜索树的插入 二叉搜索树的概念相信大家都很清楚,无非就是左小右大 创建二叉搜索树,其实就是多次调用二叉搜索树的插入方法,所以首先我们来讲讲如何插入节点到二叉搜索树里,假设一颗二叉搜索树如下 ...
- 链表(创建,插入,删除和打印输出
http://www.bianceng.cn/Programming/C/200705/327.htm (以下不全,去此网址看) 数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了 ...
- C语言实现二叉树的插入和删除
二叉树的插入删除: //首先介绍二叉树的插入://首先需要明白插入的规则:每个建好的结点p都需要从跟结点开始与根结点相比较数据域,如果根结点的数据域小于结点p,则接着将结点p与根结点的右子树相比较,否 ...
- 【Python数据结构】——二叉查找树(查找、构建、删除、插入、打印)
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/7/15 0:34 # @Author : @linlianqin # @Si ...
- c语言二叉树搜索函数,二叉树搜索c语言
广告 提供50多种云计算产品,包括云服务器和云. 创建一站式云产品试用服务,以帮助开发人员和企业以零门槛进入云环境. 例如,通用树广泛用于人工智能游戏,基于图的广度优先和深度优先搜索也广泛用于人工智能 ...
最新文章
- Apple的LZF算法解析
- 生物信息培训之WGCNA-权重基因共表达网络分析
- java 遍历写什么_Java文件遍历及文件读写
- ibatis学习笔记(三)java实体跟表映射.xml文件详解
- display(block,inline,none),visibility(visible,hidden)之间的关系及区别(不同)
- python中对多态和多态性的理解
- 华为将升级鸿蒙,华为将弃用安卓?Mate40将成为首款可升级鸿蒙OS的手机
- Spring MVC:使用基于Java的配置创建一个简单的Controller
- android 清除应用程序数据,清除Android应用程序用户数据
- GDC 2006 Microsoft Developer Day Presentations
- 百度地图添加自定义shp图层_GIS当中使用uDig打开shp图层,并查看数据结果
- 在运行SSIS包时,如何动态更新变量值
- 编译mate-control-center:error: required directory ./help does not exist
- ISO12233:2014 eSFR分辨率测试卡使用方法
- RISC-V MCU 应用教程之RTC自动唤醒
- web端调用高德API
- 硬盘分区-增加C盘容量教程
- java课程设计计算器 uml简图,计算器的用例建模
- Carson带你学Android:RxJava过滤操作符
- Java-mysql:常用SQL语句及数据库的相关操作
热门文章
- js中text方法是啥意识_一盏茶的时间,快速捕获JS中常用的方法(细心整理,持续更新ing)...
- mysql gt resource_讲解MySQL中lt;=gt;操作符的用法
- mysql1756_MySQL Error_code: 1756
- vue如何使用原生js写动画效果_原生js写一个无缝轮播图插件(支持vue)
- web前端入门学习 html5(2)
- 2019年终总结一下吧
- MyBatis源码分析——MyBatis的扩展点(pugins)
- WINCE下的MINGW交叉编译环境下内存崩溃地址的查找方法。
- springmvc+spring+hibernate集成cxf
- Java设计模式-工厂模式(3)抽象工厂模式