数据结构:详解搜索二叉树

news2025/1/22 6:36:29

目录

一、搜索二叉树的概念

二、搜索二叉树的基本结构 

 三、搜索二叉树的插入

四、搜索二叉树的查找

五 、搜索二叉树的删除


一、搜索二叉树的概念

⼆叉搜索树⼜称⼆叉排序树,它或者是⼀棵空树,或者是具有以下性质的⼆叉树:

  • 若它的左子树不为空,则左子树上所有结点的值都⼩于等于根结点的值
  • 若它的右子树不为空,则右子树上所有结点的值都⼤于等于根结点的值
  • 它的左右子树也分别为⼆叉搜索树
  • 最优情况下,⼆叉搜索树为完全⼆叉树(或者接近完全⼆叉树),其⾼度为:O(\log N
  • 最差情况下,⼆叉搜索树退化为单⽀树(或者类似单⽀),其⾼度为:O(\frac{N}{2})
  • 综合而言⼆叉搜索树增删查改时间复杂度为:O(N) 

二、搜索二叉树的基本结构 

 搜索二叉树的结构跟二叉树差不多——两个指针来指向左右子树,一个对象来存放数据。

template<class K>
struct BSTNode
{
    K _key;
    BSTNode<K>* _left;
    BSTNode<K>* _right;

    BSTNode(const K& key)
    :_key(key)
    , _left(nullptr)
    , _right(nullptr)
    {}
};

template<class K>
class BSTree
{
typedef BSTNode<K> Node;
public:
    ……
preivate:
    Node* _root = nullptr;
}

 三、搜索二叉树的插入

  1. 树为空树,new一个节点,然后赋值给_root。
  2. 树不为空树,按⼆叉搜索树性质,插⼊值比当前结点大往右走,插⼊值比当前结点小往左走,找到空位置,插⼊新结点。

注:这里不考虑插入值与节点的值相等的情况。

bool Insert(const K& key)
{
    //当_root为空树
    if (_root == nullptr)
    {
        _root = new Node(key);
        return true;
    } 

    //当_root不为空树
    //创建一个parent节点来记录上一层的位置
    //创建一个cur节点来判断插入位置
    Node* parent = nullptr;
    Node* cur = _root;
    while (cur)
    {
        if (cur->_key < key)
        {
            parent = cur;
            cur = cur->_right;
        } 
        else if (cur->_key > key)
        {
            parent = cur;
            cur = cur->_left;
        } 
        else
        {
            return false;
    }    
}

四、搜索二叉树的查找

  1. 从根开始比较,查找x,x比根的值大则往右边走查找,x比根值小则往左边走查找。
  2. 最多查找⾼度次,⾛到到空,还没找到,这个值不存在。
bool Find(const K& key)
{
    Node* cur = _root;
    while (cur)
    {
        if (cur->_key < key)
        {
            cur = cur->_right;
        } 
            else if (cur->_key > key)
        {
            cur = cur->_left;
        } 
        else
        {
            return true;
        }
    }
    return false;
}

 注:若支持插入相同的值,⼀般要求查找中序的第⼀个x,像下面这样↓,有多个值6,返回中序查找的第一个6。


五 、搜索二叉树的删除

        搜索二叉树的删除就复杂多了,会有下面四种情况:

  1. 要删除结点N左右孩子均为空。
  2. 要删除的结点N左孩子位空,右孩子结点不为空。
  3. 要删除的结点N右孩子位空,左孩子结点不为空。
  4. 要删除的结点N左右孩子结点均不为空。

 对应以上四种情况的解决⽅案:

  1. 把N结点的父亲对应孩子指针指向空,直接删除N结点(情况1可以当成2或者3处理,效果是⼀样的)
  2. 把N结点的父亲对应孩子指针指向N的右孩子,直接删除N结点
  3. 把N结点的父亲对应孩子指针指向N的左孩子,直接删除N结点
  4. 无法直接删除N结点,因为N的两个孩子无处安放,只能用替换法删除。找N左子树的值最大结点R(最右结点)或者N右子树的值最小结点R(最左结点)替代N,因为这两个结点中任意⼀个,放到N的位置,都满足⼆叉搜索树的规则。替代N的意思就是N和R的两个结点的值交换,转而变成删除R结点,R结点符合情况2或情况3,可以直接删除。

注(4):这里使用找N左子树的值最大结点R(最右结点)

bool Erase(const K& key)
{
	Node* cur = _root;
	Node* prev = nullptr;

	while(cur)
	{ 
		if (key < cur->_key)
		{
			prev = cur;
			cur = cur->_left;
		}
		else if (cur->_key < key)
		{
			prev = cur;
			cur = cur->_right;
		}
		else
		{
			//找到了
			//只有一边或没有子叶
			if (cur->_right == nullptr)
			{
				if (cur == _root)
				{
					_root = cur->_left;
				}
				else
				{
					if (prev->_right == cur)
					{
						prev->_right = cur->_left;
					}
					else
					{
						prev->_left = cur->_left;
					}
				}
				delete cur;

			}
			else if(cur->_left == nullptr)
			{
				if (cur == _root)
				{
					_root = cur->_right;
				}
				else
				{
					if (prev->_right == cur)
					{
						prev->_right = cur->_right;
					}
					else
					{
						prev->_left = cur->_right;
					}
				}
				delete cur;
			}
			else
			{
				//找到了有两个子叶
				Node* treep = cur;
				Node* treec = cur->_right;

				while (treec->_left)
				{
					treep = treec;
					treec = treec->_left;
				}

				cur->_key = treec->_key;


				if (treep->_left == treec)
					treep->_left = treec->_right;
				else
					treep->_right = treec->_right;
				delete treec;
			}
			return true;
		}
	}
	return false;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每天五分钟深度学习PyTorch:如何使用GPU来跑深度学习算法模型?

本文重点 我们前面介绍pytorch的时候,我们提到过它可以使用GPU加速,那么如何才能完成GPU的加速呢?在pytorch中非常简单,我们只需要将数据计算,模型放到GPU上就行,这样就可以使用GPU来跑深度学习算法模型了。 如何判断我们的电脑是否支持GPU pytorch中关于GPU的一些相关…

[JavaEE] IP协议

目录 一、 IP协议 1.1 基本概念 1.2 协议头格式 1.3 特殊IP 二、 地址管理 2.1 网段划分 2.2 CIDR(Classless Interdomain Routing) 2.3 私有IP地址和公网IP地址 2.4 NAT(Network Address Translation)-网络地址转换 2.5 路由选择 三、数据链路层 3.1 认识以太网 3…

嵌入式Linux系统TF卡热插拔检测问题

一、背景介绍 项目上使用linux系统&#xff0c;运行主控是君正T41&#xff0c;遇到一个系统无法识别TF卡的问题&#xff0c;经过一番探索最终成功解决。感觉挺有意思的&#xff0c;记录下分析和解决的过程。 二、现象描述 插入TF卡后系统无任何反应&#xff0c;也没有生成 /…

工业缺陷检测——Windows 10本地部署AnomalyGPT工业缺陷检测大模型

0. 引言 在缺陷检测中&#xff0c;由于真实世界样本中的缺陷数据极为稀少&#xff0c;有时在几千甚至几万个样品中才会出现一个缺陷数据。因此&#xff0c;以往的模型只需在正常样本上进行训练&#xff0c;学习正常样品的数据分布。在测试时&#xff0c;需要手动指定阈值来区分…

Java零工市场小程序如何改变自由职业者生活

如今&#xff0c;自由职业者越来越多&#xff0c;他们需要找到合适的工作机会&#xff0c;Java零工市场小程序&#xff0c;为自由职业者提供了一个方便、快捷的寻找工作机会的方式&#xff0c;这样一来&#xff0c;改变了自由职业者找寻工作的方式&#xff0c;也提高了他们的收…

DudeSuite Web Security Tools 渗透测试工具集

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 《Web安全》h…

探索私有化聊天软件:即时通讯与音视频技术的结合

在数字化转型的浪潮中&#xff0c;企业对于高效、安全、定制化的通讯解决方案的需求日益迫切。鲸信&#xff0c;作为音视频通信技术的佼佼者&#xff0c;凭借其强大的即时通讯与音视频SDK&#xff08;软件开发工具包&#xff09;结合能力&#xff0c;为企业量身打造了私有化聊天…

vue3学习记录-computed

vue3学习记录-computed 1.为什么要用computed2.使用方法2.1 基本实例2.2 可写计算属性 1.为什么要用computed 写个购物车的案例 <script setup> import { ref, reactive,computed } from "vue" const tableData reactive([{ name: 商品1, price: 10, num: 1…

Mysql数据库相关操作总结

目录 1.背景知识 2.创建数据库 2.1创建指令 2.2字符集 3.查看数据库 3.选中数据库 4.删除数据库 5.数据表的操作 5.1基本数据类型 5.2创建表 5.3查看所有的表 5.4查看表的结构 5.5删除表 6.CRUD增删查改 6.1新增和效果查看 6.3删除 6.4查找 1.背景知识 数据库就…

微pe和u深度pe哪个好用_微pe和u深度pe对比分析

大家在安装系统时都喜欢用pe来安装&#xff0c;pe安装系统的好处就是稳定可靠&#xff0c;不担心进不了系统。最近有网友问我&#xff0c;微pe和u深度pe哪个好用?下面小编就给大家分析一下微pe和u深度pe对比分析。 微pe和u深度pe哪个好用? 微PE好&#xff0c;目前公认良心PE…

【JavaScript】JQuery基础知识及应用

一、JQuery的导入方法 https://editor.csdn.net/md/?articleId132214798 二、JQuery介绍 JQuery(JQ)&#xff1a;JS的一个类库&#xff08;方法库&#xff1a;包含了大量的、有助于项目开发的属性和方法&#xff09; 第一代版本1.xx.xx: 1.11.3 兼容所有浏览器的&#xff0…

iOS 项目中的多主题颜色设计与实现

引言 在现代iOS应用中&#xff0c;用户对个性化体验的需求越来越高&#xff0c;除了功能上的满足&#xff0c;多样的视觉风格也是提升用户体验的重要手段之一。提供多主题颜色的切换功能不仅能满足用户的审美偏好&#xff0c;还可以让应用更具活力&#xff0c;适应不同场景下的…

在LLMs模型中发现人类的记忆特征

论文地址&#xff1a;https://arxiv.org/abs/2311.03839 介绍 大型语言模型&#xff08;LLM&#xff09;&#xff0c;如 ChatGPT&#xff0c;为语言建模和生成人类水平的文本输出带来了质的飞跃。 这些模型在庞大的文本库中进行训练&#xff0c;有效地建立了高度复杂和准确的…

队列——单调队列

题目描述 有一个大小为 k 的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 例如&#xff1a;[1, 3, −1, −3, 5, 3, 6, 7] k3。 有一个长为 n 的序列 a&#xff0c;以及一个大小为 k 的窗口。现在这个从…

哈希表(HashMap、HashSet)

文章目录 一、 什么是哈希表二、 哈希冲突2.1 为什么会出现冲突2.2 如何避免出现冲突2.3 出现冲突如何解决 三、模拟实现哈希桶/开散列&#xff08;整型数据&#xff09;3.1 结构3.2 插入元素3.3 获取元素 四、模拟实现哈希桶/开散列&#xff08;泛型&#xff09;4.1 结构4.2 插…

javaweb之会话管理

Cookie&#xff1a; 1. Cookie 的定义 Cookie 是存储在用户浏览器中的小块数据&#xff0c;通常由服务器发送并存储&#xff0c;以便在用户浏览器和服务器之间保持会话状态。每次用户发送请求时&#xff0c;浏览器都会自动附带相应的 Cookie&#xff0c;允许服务器辨识用户。…

58 深层循环神经网络_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录深度循环神经网络1. 模型复杂性增加2. 训练数据不足3. 梯度消失和爆炸4. 正则化不足5. 特征冗余总结 函数依赖关系简洁实现训练与预测小结练习 深度循环神经网络 &#x1f3f7;sec_deep_rnn 到目前为止&#xff0c;我们只讨论了具有一个单…

基于大数据的亚健康人群数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

在vsCode中将某个字符替换成换行符并且换行展示

将下面一行字符串中的“,”替换成换行符并且换行展示。 CTRLF键检索&#xff0c;查找和替换内容根据如下图输入即可。 点击全部替换后得到如下结果&#xff1a;

图文深入理解Oracle Network配置管理(二)

本篇图文深入介绍Oracle Network配置管理。 Oracle网络配置的目的 为了方便对Oracle 数据库进行管理&#xff0c;一般以下情况应该对Oracle进行网络配置。 • 在客户端对服务器端数据库进行管理&#xff08;网络客户端管理&#xff09; • 在一台服务器上管理多个数据库&…