完全理解搜索/排序/查找二叉树的插入、查找、删除

2023-11-10

目录

一.插入

(一).实现原理

(二).代码实现

二.查找

(一).实现原理

(二).代码实现

三.删除

(一).实现原理

(二).代码实现


这种二叉树名字太多了!小编这里统一叫做搜索二叉树了。

首先让我们看看搜索二叉树长什么样子:

41ade014a2a4581290830b23882348e3.png

图片来源:二叉树 -- 二叉排序树 - 简书 (jianshu.com)

一.插入

(一).实现原理

实现搜索二叉树的插入操作,我们只需要将要插入的元素大小与经过的节点做比较,元素比该节点小就往节点左边走,元素比该节点大就往节点右边走,直到该元素找到一个空区域(NULL),把该元素插入这个空白区域即可。

图片说明就是这样:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCx6KaBIOWuheWcqOWutg==,size_20,color_FFFFFF,t_70,g_se,x_16

(二).代码实现

typedef int Treetype;
typedef struct binaryTree
{
	Treetype  val;
	struct binaryTree* left, * right;
}BinaryTree;
void Push_BST(BinaryTree* bt, Treetype n)//输入元素,建树
{
    if (bt->val == MAXNUM)//树中还没有元素
	{
		bt->val = n;
		return;
	}
	if (n <= bt->val)//元素比该树节点小
	{
		if (bt->left)//如果节点左边非空,继续递归比较
			Push_BST(bt->left, n);
		else//节点左边空的话就插入此位置
		{
			BinaryTree* tmp = (BinaryTree*)new BinaryTree;
			tmp->left = tmp->right = NULL;
			tmp->val = n;
			bt->left = tmp;
			return;
		}
	}
	else//元素比该树节点大
	{
		if (bt->right)
			Push_BST(bt->right, n);
		else
		{
			BinaryTree* tmp = (BinaryTree*)new BinaryTree;
			tmp->left = tmp->right = NULL;
			tmp->val = n;
			bt->right = tmp;
			return;
		}
	}
}

二.查找

(一).实现原理

查找的原理与插入的类似

我们将要查找的元素与经过的每个节点做比较,如果元素与该节点的值相等,那就返回该节点就可;如果比该节点小就往节点的左子树走,如果比该节点大就往节点的右子树走。

直到找到与该元素相同的节点或走到空白位置即该树中没有与该元素相同的节点

(二).代码实现

bool Search_BST(BinaryTree* bt, Treetype n)//查找
{
	if (bt == NULL) return false;
	else if (bt->val == n) return true;
	return n < bt->val ? Search_BST(bt->left, n) : Search_BST(bt->right, n);
}

三.删除

(一).实现原理

删除的原理相对较难一些。

我们需要进行分类讨论。

第一种情况:删除的节点没有左右子树。

        这是最简单的情况,我们直接删除这个节点即可。

第二种情况:删除的节点只有左子树或者只有右子树。

        这里我们以只有左子树为例,我们只需要把该删除节点的左子树接上即可。

第三种情况:删除的节点既有左子树,又有右子树(最重要)

        大家跟着我一起来想:搜索二叉树的性质是比该节点小的都在左边,大的都在右边。

那么我们只需要在该节点的左边找到最大的或者在节点右边找到最小的即可,因为这两个都是最接近要删除的节点值的。把这两个最接近值中的其中一个与删除节点值交换,然后将交换后删除值所在的节点删除即可。

那么我们怎么找到这个最接近的值呢:

①节点左边最大的(直接前驱):找到删除节点的左子树的最右边子树即可。因为,删除节点的左子树是比该节点小的,而该左子树的右子树是大于该左子树又小于删除节点的,然后一直往右走,直到找到最右边的子树,这颗树是大于删除节点所有左节点又小于删除节点的,即最接近删除节点的。

①节点右边最小的(直接后继):找到删除节点的右子树的最左边子树即可。道理同直接前驱。

        当然,我们还是用图来说明一下吧,这里用直接前驱来解释:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCx6KaBIOWuheWcqOWutg==,size_20,color_FFFFFF,t_70,g_se,x_16

注意:这里有一个陷阱!

        如果删除节点的左子树没有右节点那么就无法与要删除的节点交换,这里我们只需要在一开始确定删除节点左右子树非空的情况下,再判断左节点是否有有子树即可,没有右子树的话直接把左节点接到删除节点即可。 

(二).代码实现

void Pop_BST(BinaryTree* bt, Treetype n)//删除元素
{
	if (bt == NULL)//没找到
	{
		cout << "Pop false! No find it.\n";
		return;
	}
	else if (bt->val == n)
	{
		_pop(bt);
	}
	else
	n < bt->val ? Pop_BST(bt->left, n) : Pop_BST(bt->right, n);
}
void _pop(BinaryTree* bt)//删除的子函数
{
	if (bt->left == NULL)//左空、全空
	{
		BinaryTree* tmp = bt;
		bt = bt->right;
		free(tmp);
	}
	else if (bt->right == NULL)//右空
	{
		BinaryTree* tmp = bt;
		bt = bt->left;
		free(tmp);
	}
	else//左右子树都不是空
	{
		//采用找直接前驱的方法
		BinaryTree* prev = bt->left, *rtmp = bt->left->right, *tmp = bt;
		if (rtmp == NULL)//bt的左子树没有右子树
		{
			bt->val = bt->left->val;
			bt->left = bt->left->left;
			free(prev);
			return;
		}
		while (rtmp->right)//找左子树的最右节点
		{
			prev = rtmp;
			rtmp = rtmp->right;
		}
		bt->val = rtmp->val;
		prev->right = rtmp->left;
		free(rtmp);
	}
}

 创作不易,点赞支持博主一下吧

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

完全理解搜索/排序/查找二叉树的插入、查找、删除 的相关文章

随机推荐

  • 前端JS笔记

    JS笔记 持续更新中
  • c语言string函数作用,浅谈C语言之字符串处理函数

    下面介绍8种基本的常用的字符串处理函数 在数值数组中也常常用到 部分函数 所有的C语言编译系统中一般都提供这些函数 1 puts函数 输出字符串的函数 一般的形式为puts 字符串组 作用 将一个字符串输出到终端 如 char一个strin
  • CAD卸载/完美解决安装失败/如何彻底卸载清除干净cad各种残留注册表和文件的方法...

    在卸载cad重装CAD时发现安装失败 提示是已安装或安装失败 这是因为上一次卸载后没有清理干净 系统会误认为已经安装过了 有的同学是新装的系统也会出现安装失败的情况 这是因为C 或者 NET的原因 无论任何版本的cad在手动删除卸载之后都会
  • nginx查看php错误日志,nginx php-fpm输出php错误日志的方法

    nginx php fpm输出php错误日志的方法 发布时间 2020 08 15 11 03 12 来源 亿速云 阅读 137 作者 小新 nginx php fpm输出php错误日志的方法 这个问题可能是我们日常学习或工作经常见到的 希
  • B+树结构与索引<一> _ 结构与索引

    目录 一 B 树结构 1 二分查找法 2 二叉查找树 3 平衡二叉树 4 平衡多路查找树 B Tree 5 B 树 二 操作B 树 1 插入操作 2 删除操作 三 B 树索引类型 1 聚集索引 clustered index 2 辅助索引
  • == 和 equals 的区别是什么

    解读 对于基本类型和引用类型 的作用效果是不同的 如下所示 基本类型 比较的是值是否相同 引用类型 比较的是引用是否相同 equals 解读 equals 本质上就是 只不过 String 和 Integer 等重写了 equals 方法
  • 给你的类重写Equals--检测Class是否相等

    在C 的容器中 常用的三个容器数组 ArrayList Hashtable 数组比较简单 实现某种单一数据的存储 但是并不能自由插入 移除和容纳不同的对象 所以ArrayList是数组的替代品 并且由于ArrayList可以自由的添加 删除
  • 调用接口时 net::ERR_CERT_AUTHORITY_INVALID

    调用接口控制台报错net ERR CERT AUTHORITY INVALID network栏也是红色 这种一般的情况是证书不被浏览器认可 检查下证书 我的情况是我在本地模拟的https 生成的模拟证书 所以是不被浏览器认可的 解决方案
  • centos-6.8下载与安装

    一 centos的下载 有了需要自己才会去动手 算是配置开发环境的一些记录吧 首先进入官网 https www centos org download 官网页面 全英文的界面 英语不是很好 但容易找到 list of current mir
  • PROFINET工业以太网教程---GSDML文件详解

    前面的文章 PROFINET工业以太网教程 10 GSD文件 我们介绍过GSD文件 它的全称是 General Station Description 中文翻译为 通用站描述文件 GSD文件的主要作用是对PROFINET或PROFIBUS子
  • java课设带app_IPAssignApp.java

    package tsinghuaip import javax swing UIManager import java awt public class IPAssignApp boolean packFrame false Constru
  • Java 描述将数字金额转换为中文大写

    Java 描述金额转换 数字转换成中文大写 解题思路 把每一位转换成对应的大写 然后在不足地方补零 最后加上相应单位 代码如下 import java util Scanner public class Main public static
  • 入门汇编(简单程序设计)

    将TABLE单元的10个字节数据传送到TABLE 5开始的单元 MOV CX 10 LEA SI TABLE LEA DI TABLE ADD DI 14 ADD SI 9 STD REP MOVSB 计算 X Y X 结果存Z单元 商是A
  • 多态的定义及其实现

    1 什么是多态性 多态性可以简单地概括为 一个接口 多种方法 程序在运行时才决定调用的函数 它是面向对象编程领域的核心概念 只有重写虚函数才体现C 的多态性 虚函数 虚函数对于多态具有决定性的作用 有虚函数才能构成多态 只需要在虚函数的声明
  • 您选择的文件不是有效的iso映像文件,请重新选择

    安装windows系统的时候无非就是参考类似于下面的这些博文 通用PE u盘装Ghost Win10系统教程http www tongyongpe com win10ghost html 用U盘装机大师安装GHOST WIN10系统http
  • React入门教程之井字棋(三)——游戏完善

    我们现在已经编写好了井字棋游戏中 最基础的可以落子的棋盘 为了开发一个完整的游戏 我们还需要交替在棋盘上放置 X 和 O 并且判断出胜者 状态提升 当前 每个 Square 组件都维护了游戏的状态 我们可以把所有 9 个 Square 的值
  • git删除分支,本地分支、远程分支

    前言 git删除分支的命令 目标 我们这里来删除git的 dev 分支 步骤 一 查看所有的分支 git branch a 查看当前所有的分支 git branch 查看当前所在分支 二 删除本地的分支 git branch D dev 先
  • Linux入门(一)——Linux开源版本的对比

    Linux开源版本的对比 CentOS Ubuntu Debain Debain 优点 稳定 占用空间小 不足 帮助文档相对CentOS少 技术资料也比较少 CentOS CentOS是从RedHat源代码编译的社区重新发布版 CentOS
  • docker stats监控容器资源消耗

    在容器的使用过程中 如果能及时的掌握容器使用的系统资源 无论对开发还是运维工作都是非常有益的 幸运的是 docker 自己就提供了这样的命令 docker stats 默认输出 docker stats 命令用来显示容器使用的系统资源 不带
  • 完全理解搜索/排序/查找二叉树的插入、查找、删除

    目录 一 插入 一 实现原理 二 代码实现 二 查找 一 实现原理 二 代码实现 三 删除 一 实现原理 二 代码实现 这种二叉树名字太多了 小编这里统一叫做搜索二叉树了 首先让我们看看搜索二叉树长什么样子 图片来源 二叉树 二叉排序树 简