深入了解二叉搜索树:原理、操作与应用

文章目录

  • 二叉搜索树
    • 二叉搜索树的操作
    • 1.查找操作
    • 2.插入操作
    • 3.查找最大值或者最小值
    • 4.删除操作
    • 5.前序中序后序遍历
  • 总结

在这里插入图片描述

二叉搜索树

在这里插入图片描述

形如上图的二叉树就是二叉搜索树,接下来我们来具体阐述一下什么是二叉搜索树。

二叉搜索树的概念:满足左子树的值小于根节点,右子树的值大于根节点的值,这样的树就是二叉搜索树

二叉搜索树的性质:
1.二叉搜索树的中序遍历呈现单调递增的性质。
2.二叉搜索树的每个节点的值都具有唯一性。

二叉搜索树的操作

对于普通的二叉树来说,增删查改没有意义,但是对于二叉搜索树来说增删查改便有了意义,接下来,我们来研究二叉搜索树的增删查改等等一系列操作。
首先我们先定义一个二叉搜索树,二叉搜索树的定义和二叉树的定义相同:

class TreeNode
{
public:
private:
	int _val;
	TreeNode* _left;
	TreeNode* _right;
};
class BST
{
public:
private:
	TreeNode* _root;
};

上面就是二叉搜索树的定义

接下来我们来写一下二叉搜索树的接口,,我们先将其列在BST

class BST
{
public:
	//初始化
	BST();
	//查找
	bool Search(int val);
	bool SearchNode(TreeNode* Node, int val);
	//插入
	void Insert(int val);
	TreeNode* InsertNode(TreeNode* Node, int val);
	//删除
	void Delete(int val);
	TreeNode* AssistDelete(TreeNode* Node, int val);
	TreeNode* FindPrev(TreeNode* root, TreeNode* Node);
	//查找最大值或者最小值
	int GetMin();
	TreeNode* AssistGetMin(TreeNode*Node);
	int GetMax();
	TreeNode* AssistGetMax(TreeNode* Node);
	//后序遍历
	void PostOrder();
	void AssistPostOrder(TreeNode* Node);
	//中序遍历
	void InOrder();
	void AssistInOrder(TreeNode* Node);
	//前序遍历
	void PrevOrder();
	void AssistPrevOrder(TreeNode* Node);
private:
	TreeNode* _root;
};

接下我们一个一个来探讨

1.查找操作

//查找
bool Search(int val);
bool SearchNode(TreeNode* Node, int val);

找到了返回true,没找到返回false
对于普通的二叉树来说我们需要遍历整个树对其进行查找,而且可能二叉树中还有重复值的节点,但是对于二叉搜索树就没有这种麻烦,当我们要搜索一个数时,只需要将这个数和根节点的值进行比较,如果比根节点的数大就递归到右边,如果比根节点的数小就递归左边,不需要整个树都递归。

我们来看看具体代码:

bool BST::Search(int val)
{
	return SearchNode(_root, val);
}
//辅助函数
bool BST::SearchNode(TreeNode* Node, int val)
{
	//找到了nullptr就说明没找到,直接返回false
	if (Node == nullptr)
	{
		return false;
	}
	//判断val的位置,对左子树或者右子树进行递归
	if (Node->_val == val)
	{
		return true;
	}
	else if (val < Node->_val)
	{
		return SearchNode(Node->_left, val);
	}
	else
	{
		return SearchNode(Node->_right, val);
	}
}

2.插入操作

对于普通二叉树来说,插入操作没有意义,因为每一个地方都可以插入,并没有实际意义,但是对于二叉搜索树来说就有意义了,对于二叉搜索树来说,插入操作具有唯一性,可以维护二叉搜索树的排序的性质。

//插入
void Insert(int val);
TreeNode* InsertNode(TreeNode* Node, int val);

查到插入位置然后返回,InsertNode是一个辅助函数。
具体代码:

void BST::Insert(int val)
{
	_root = InsertNode(_root, val);
}
TreeNode* BST::InsertNode(TreeNode* Node, int val)
{
	//当Node==nullptr的时候说明找到了插入的位置
	if (Node == nullptr)
	{
		创造一个新的节点,用val进行初始化
		return new TreeNode(val);//创建一个节点
	}
	//判断递归的范围
	if (Node->_val < val)
	{
		Node->_right = InsertNode(Node->_right, val);
	}
	else if (Node->_val > val)
	{
		Node->_left = InsertNode(Node->_left, val);
	}
	//最后返回Node
	return Node;
}

3.查找最大值或者最小值

//查找最大值或者最小值
int GetMin();
TreeNode* AssistGetMin(TreeNode*Node);
int GetMax();
TreeNode* AssistGetMax(TreeNode* Node);

由于二叉搜索树的特殊性质,左子树的值一定比右子树小,说明最大值一定在右子树的最右边的一个节点上,而最小值一定在左子树的最左边的一个节点上。

我们来看看代码:

//查找最小值
int BST::GetMin()
{
	//根节点为空的时候,说明没有,直接返回INT_MAX
	if (_root == nullptr)
	{
		return INT_MAX;
	}
	//找到最小值的节点
	TreeNode* min = AssistGetMin(_root);
	//返回最小值
	return min->_val;
}
TreeNode* BST::AssistGetMin(TreeNode* Node)
{
	//直接递归左子树,当左子树指向的左边是空的时候直接返回当前节点
	if (Node->_left == nullptr)
	{
		return Node;
	}
	//递归左子树
	return AssistGetMin(Node->_left);
}
//查找最大值
int BST::GetMax()
{
	//同上
	if (_root == nullptr)
	{
		return INT_MAX;
	}
	//找到最大值对应的节点
	TreeNode* max = AssistGetMax(_root);
	//返回最大值
	return max->_val;
}
TreeNode* BST::AssistGetMax(TreeNode* Node)
{
	//判断边界条件
	if (Node->_right == nullptr)
	{
		return Node;
	}
	//递归右子树
	return AssistGetMax(Node->_right);
}

4.删除操作

//删除
void Delete(int val);
TreeNode* AssistDelete(TreeNode* Node, int val);
TreeNode* FindPrev(TreeNode* root, TreeNode* Node);

对于删除操作存在三种情况:
1. 删除的当前节点的左节点和右节点都是nullpt
2. 删除的当前节点的的左节点或者右节点当中存在一个节点,有一个节点是nullpt
3. 删除的当前节点的左节点和右节点都不为nullptr

对于删除操作我们还需要一个函数就是能找到前一个节点的函数,当我们删除了一个节点之后,我们需要找到前一个节点将它与后一个节点连接起来,还需要一个函数就是我们刚刚写的找最大值的函数或者找最小值的函数,这里我们就用找最小值的函数,对于删除的当前节点的左节点和右节点都不为空的时候,我们需要有一个节点来重新构造一下这个二叉搜索树,这里有个技巧,就是我们需要的节点就是当前节点的左子树的最大值的节点或者是右子树的最小值的节点充当本节点。

代码展示:

void BST::Delete(int val)
{
	_root = AssistDelete(_root, val);
}
//找到前一个节点
TreeNode* BST::FindPrev(TreeNode* root, TreeNode* Node)
{
	if (root->_left == Node || root->_right == Node)
	{
		return root;
	}
	if (root->_val < Node->_val)
	{
		FindPrev(root->_right, Node);
	}
	if (root->_val > Node->_val)
	{
		FindPrev(root->_left, Node);
	}
}
//删除操作
TreeNode* BST::AssistDelete(TreeNode* node, int val)
{
	//当node==nullptr说明没有满足条件的删除节点,直接返回nullpr
	if (node == nullptr)
	{
		return node;
	}
	// 找到要删除的节点
	if (val < node->_val)
	{
		node->_left = AssistDelete(node->_left, val);
	}
	else if (val > node->_val)
	{
		node->_right = AssistDelete(node->_right, val);
	}
	//找到了之后进入else进行删除操作
	else
	{
		// 要删除的节点有一个或没有孩子
		if (node->_left == nullptr)
		{
			TreeNode* temp = node->_right;
			delete node;
			return temp;
		}
		else if (node->_right == nullptr)
		{
			TreeNode* temp = node->_left;
			delete node;
			return temp;
		}

		// 要删除的节点有两个孩子
		// 找到要删除节点的后继节点(右子树中的最小节点)
		TreeNode* temp = AssistGetMin(node->_right);
		// 将后继节点的值复制到要删除的节点中
		node->_val = temp->_val;
		// 递归删除后继节点
		node->_right = AssistDelete(node->_right, temp->_val);
	}
	//返回
	return node;
}

5.前序中序后序遍历

	//后序遍历
	void PostOrder();
	void AssistPostOrder(TreeNode* Node);
	//中序遍历
	void InOrder();
	void AssistInOrder(TreeNode* Node);
	//前序遍历
	void PrevOrder();
	void AssistPrevOrder(TreeNode* Node);

和普通二叉树相同

void BST::PostOrder()
{
	AssistPostOrder(_root);
}
void BST::AssistPostOrder(TreeNode* Node)
{
	if (Node == nullptr)
	{
		return;
	}
	AssistPostOrder(Node->_left);
	AssistPostOrder(Node->_right);
	cout << Node->_val << ' ';
}
void BST::InOrder()
{
	AssistInOrder(_root);
}
void BST::AssistInOrder(TreeNode* Node)
{
	if (Node == nullptr)
	{
		return;
	}
	AssistInOrder(Node->_left);
	cout << Node->_val << ' ';
	AssistInOrder(Node->_right);
}
void BST::PrevOrder()
{
	AssistPrevOrder(_root);
}
void BST::AssistPrevOrder(TreeNode* Node)
{
	if (Node == nullptr)
	{
		return;
	}
	cout << Node->_val << ' ';
	AssistPrevOrder(Node->_left);
	AssistPrevOrder(Node->_right);
}

总结

总的来说,二叉搜索树(BST)作为一种重要的数据结构,在计算机科学领域发挥着重要作用。通过其排序性质和高效的搜索、插入和删除操作,二叉搜索树成为了解决各种问题的有力工具。

在本博客中,我们深入探讨了二叉搜索树的概念、性质和操作。我们了解到,二叉搜索树具有自平衡的能力,能够在平均情况下保持较低的时间复杂度。同时,我们也注意到了在极端情况下,二叉搜索树可能会退化为链表,导致操作的时间复杂度上升。因此,在实际应用中,需要考虑树的平衡性,以保证其性能。

通过本博客,希望读者能够深入理解二叉搜索树的工作原理,并且能够运用这一数据结构解决实际问题。同时,也希望读者能够进一步探索二叉搜索树的相关内容,如平衡二叉搜索树(如AVL树和红黑树)以及其他高级数据结构,从而拓展自己的知识领域。

最后,二叉搜索树是计算机科学中的基础之一,深入了解它将有助于我们更好地理解和应用数据结构与算法,提高编程能力,并解决更复杂的计算问题。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/609256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

winform图书销售管理系统+mysql

winform图书销售管理系统mysql数据库说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 功能模块&#xff1a; 管理员:ttt 123 登陆可以操作我的 个人信息 修改密码 用户信息 添加删除用户 图书 添加删除图书信息 购物车 购买订单信息 充值 退出账户 …

网络安全之弱口令与命令爆破(下篇)(技术进阶)

目录 一&#xff0c;什么是弱口令&#xff1f; 二&#xff0c;为什么会产生弱口令呢&#xff1f; 三&#xff0c;字典的生成 四&#xff0c;九头蛇&#xff08;hydra&#xff09;弱口令爆破工具 1&#xff0c;破解ssh登录密码 2&#xff0c;破解windows登录密码 3&#xf…

Cesium的使用和特点

Cesium 是一款开源的 JavaScript 库&#xff0c;用于在 Web 上可视化地理空间数据。它广泛用于创建 3D 地球、地图和其他地理空间应用程序。Cesium 具有以下特点使其成为地理空间开发的流行选择。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交…

华为OD机试 - 手机App防沉迷系统(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

git合并分支

1、vscode安装插件Git Graph 2、点击右下角分支&#xff0c;比如要把dev分支合并到其他分支 首先dev分支的全部提交了&#xff0c;然后切换到其他分支 3、选择被合并的分支 点提交就好了

中医课堂丨名医面对面,金保方教授专场健康科普交流圆满举行

5月8日下午&#xff0c;李良济特邀金保方教授&#xff0c;在苏州太湖国际高尔夫俱乐部&#xff0c;以“生殖健康漫谈”为主题开展专场科普交流活动&#xff0c;参与的嘉宾表示受益匪浅&#xff0c;反响强烈。 本次活动主要包含了专家讲座、专家答疑义诊&#xff0c;现在就让我…

Java基础编程(高级部分)

1. 类变量和类方法 1.1 什么是类变量 类变量也叫静态变量/静态属性&#xff0c;是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值同样任何一个该类的对象去修改它时,修改的也是同一个变量。 1.2 定义类变量 1.3 访问类变量 类名.类变量名 或者 对…

【GD32H757Z海棠派使用手册】第七讲 FWDG-看门狗实验

7.1 实验内容 通过本实验主要学习以下内容&#xff1a; 独立看门狗的原理 独立看门狗功能介绍 实现独立看门狗功能 7.2 实验原理 7.2.1 看门狗的原理 一般来说&#xff0c;搭配MCU的产品都需要有长期运行的需求&#xff0c;特别像一些工业设备&#xff0c;可能要求运行个…

微信团队开源的跨平台数据库框架 | 开源日报 No.249

Tencent/wcdb Stars: 10.4k License: NOASSERTION wcdb 是由微信开发的跨平台数据库框架。 该项目主要功能、关键特性、核心优势包括&#xff1a; 易于使用ORM&#xff08;对象关系映射&#xff09;WINQ&#xff08;WCDB 语言集成查询&#xff09;高效性能多线程并发支持完备…

element ui的无法关掉的提示弹框

使用element的$alert组件的属性把X去掉和确定按钮和取消按钮去掉&#xff1b; import { MessageBox } from element-ui; MessageBox.alert(AI功能已到期或暂未开启, 友情提示, {showClose: false,showCancelButton: false,showConfirmButton: false }); 如果在router的路由守…

QX------mini51单片机学习------(5)数码管的静态与动态显示

目录 1数码管应用场景 2数码管显示原理 3静态与动态显示 474HC573锁存器工作原理 5上拉电阻的作用 6原理图分析 7实践 1数码管应用场景 2数码管显示原理 图&#xff08;b&#xff09;左边是共阴极&#xff0c;右边是共阳极 GND是公共极&#xff0c;可以用万用表测&am…

C盘文件清理

WinSxS里面的文件是不可删除的。WinSxS下有很多重要的组件&#xff0c;版本也很繁杂&#xff0c;为了保证Windows的正常运行&#xff0c;请确保这些文件一个都不能少。这些文件支撑着mscorwks.dll&#xff0c;没有它们&#xff0c;mscorwks也无法加载。强行删除后可能只有以安全…

NASA数据集——全球土壤顶部 1 厘米土壤湿度的网格估算值25km分辨率

AMSR-E/Aqua L2B Surface Soil Moisture, Ancillary Parms, & QC EASE-Grids V003 简介 该数据集包含土壤顶部 1 厘米土壤湿度的网格估算值&#xff0c;是 AMSR-E 检索足迹的平均值。土壤湿度是通过 AMSR-E/Aqua L2A亮度温度&#xff08;Tb&#xff09;测量值估算的&…

远程连接是什么?

远程连接是指通过网络连接两个或多个设备&#xff0c;实现远程访问、控制或传输数据的技术。它在现代科技发展中起到了重要作用&#xff0c;使得我们可以随时随地与远程设备进行交互、管理和操作。 天联组网是一种高效的远程连接解决方案&#xff0c;它因为操作简单、跨平台应用…

「51媒体」教育论坛会议媒体邀约的资源有哪些

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 中国拥有众多教育方面的媒体资源&#xff0c;这些媒体在邀约时可以用于宣传和推广教育活动、论坛或项目。以下是一些具体的教育媒体邀约资源&#xff1a; 报纸类媒体&#xff1a; 《中…

MySQL库操作 表操作【详细解析】

MySQL MySQL是一个数据库软件 mysql mysql是一个“客户端—服务器”结构的软件 (1) a.客户端&#xff1a;主动发起请求的一方&#xff08;Client&#xff09; b.服务器&#xff1a;被动接收请求的一方&#xff08;Server&#xff09; 客户端和服务器之间通过网络 进行通信 (…

【Stylus详解与引入】

文章目录 Stylus详解与引入一、Stylus简介二、Stylus的特性1. 变量2. 嵌套规则3. 混合&#xff08;Mixins&#xff09;4. 函数5. 条件语句和循环 三、Stylus的引入与配置1. 安装Stylus和stylus-loader2. 配置Webpack3. 在Vue项目中使用Stylus4. 编译Stylus代码四、Stylus的性能…

美国商务部公布数字孪生技术投资计划

文章目录 前言一、主要内容二、相关背景‍‍‍‍前言 5月6日,美国商务部公布了一项价值2.85亿美元的投资计划,这项名为《美国芯片制造研究竞标》(CHIPS Manufacturing USA Institute Competition)的投资计划旨在向符合条件的申请者进行征求招标,协调建立和运营美国芯片制…

LeetCode-2079. 给植物浇水【数组 模拟】

LeetCode-2079. 给植物浇水【数组 模拟】 题目描述&#xff1a;解题思路一&#xff1a;简单的模拟题&#xff0c;初始化为0&#xff0c;考虑先不浇灌每一个植物解题思路二&#xff1a;初始化为n&#xff0c;考虑每一个植物需要浇灌解题思路三&#xff1a;0 题目描述&#xff1a…

量子城域网建设设备系列(三):网络管理系统(NMS)

在量子保密通信网络中&#xff0c;需要对整个网络的设备进行集中管理和统一维护。主要包括对设备的状态监控、异常告警的采集分析、拓扑管理、设备参数配置、业务策略控制等功能。基于这些需求&#xff0c;在实际的工程应用中&#xff0c;我们通常采用量子网络管理系统&#xf…