C++系列-二叉搜索树

news2024/10/4 21:06:09

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

二叉搜索树

 二叉搜索树又称二叉排序树,它或者是一颗空树,或者是具有以下性质的树

  • 若它的左子树不为空,则左子树上的所有节点的值都小于根节点的值。
  • 若它的右子树不为空,则右子树上的所有节点的值都大于根节点的值。
  • 它的左右字数也分别为二叉搜索树。

 二叉树在我们之前讲数据结构的时候完成过二叉树的实现,在二叉树中,每个节点都会指向它的左右节点,所以,我们可以先初步实现二叉搜索树当中的每个节点。

template<class K>
class 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:
	bool Insert(const K& key);
	bool Find(const K& key);
	bool Erase(const K& key);
	void Inorder();
private:
	void _Inorder(Node* root);
private:
	Node* _root = nullptr;
};

接下来,让我们逐步分析一下每个功能的具体实现方式。

查找

因为二叉搜索树实现插入功能需要用的查找功能,所以,我们先来实现查找这个函数。

  • 从根开始查找,比根大去右边,比根小去左边
  • 找到的话,返回true,找不到,返回false
	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;
	}

 插入

  • 树为空,则直接新增节点,赋值给root指针
  • 树不为空,则查找插入的位置,插入新节点。
	bool Insert(const K& key)
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else if (cur->_key > key)
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(key);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		return true;
	}

在这个当中,我们要记得定义一个父亲节点,便于找到后进行插入操作。

删除

	bool Erase(const K& key)
	{
		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
			{
				//删除
				//0-1个孩子的情况
				if (cur->_left = nullptr)
				{
					if (parent == nullptr)
					{
						_root = cur->_right;
					}
					else
					{
						if (parent->_left == cur)
						{
							parent->_left = cur->_right;
						}
						else
							parent->_right = cur->right;
					}
					delete cur;
					return true;
				}
				else if (cur->_right == nullptr)
				{
					if (parent == nullptr)
					{
						_root = cur->_left;
					}
					else
					{
						if (parent->_right == cur)
						{
							parent->_right = cur->_left;
						}
						else
							parent->_left = cur->_left;
					}
					delete cur;
					return true;
				}
				else
				{
					//两个孩子的情况
					//右子树的最小节点作为替代节点
					Node* rightMinp = cur;
					Node* rightMin = cur->_right;
					while (rightMin->_left)
					{
						rightMinp = rightMin;
						rightMin = rightMin->_left;
					}
					cur->_key = rightMin->_key;
					if (rightMinp->_left = rightMin)
						rightMinp->_left = rightMin->_right;
					else
						rightMinp->_right - rightMin->_right;
					delete rightMin;
					return true;
				}
			}
		}
		return false;
	}

中序遍历

	void Inorder()
	{
		_Inorder(_root);
		cout << endl;
	}
private:
	void _Inorder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_Inorder(_root->_left);
		cout << _root->_key << " ";
		_Inorder(_root->_right);
	}

 好了,本次的文章就到这里了,我们下次再见。 

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

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

相关文章

大数据实时数仓Hologres(四):基于Flink+Hologres搭建实时数仓

文章目录 基于FlinkHologres搭建实时数仓 一、使用示例 二、方案架构 1、架构优势 2、Hologres核心优势 三、实践场景 四、项目准备 1、创建阿里云账号AccessKey 2、准备MySQL数据源 五、构建实时数仓​编辑 1、管理元数据 2、构建ODS层 2.1、创建CDAS同步作业OD…

鸿蒙网络管理模块03——多播DNS管理

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 1、概述 多播DNS也简称MDNS(Multicast DNS)&#xff0c;他主要提供局域网内的本地服…

NVIDIA Ampere 架构

全球超强弹性数据中心的核心。 文章目录 前言一、突破性创新1. 第三代 Tensor 核心2. 多实例 GPU (MIG)3. 第三代 NVLink4. 结构化稀疏5. 第二代 RT 核心6. 更聪明、快速的内存二、为规模化部署而优化1. 为各种服务器优化性能2. 统一计算和网络加速3. 密度优化的设计4. 安全部署…

leetcode练习 路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22 输出&a…

ElasticSearch备考 -- 查询模版

一、题目 ### 基础版 Create a search template for the above query, so that the template (i) is named "with_response_and_tag", (ii) has a parameter "with_min_response" to represent the lower bound of the response field, (iii) has a parame…

二叉树进阶学习——从前序和中序遍历序列构造二叉树

1.题目解析 题目来源&#xff1a;105.从前序与中序遍历序列构造二叉树——力扣 测试用例 2.算法原理 首先要了解一个概念 前序遍历&#xff1a;按照 根节点->左子树->右子树的顺序遍历二叉树 中序遍历&#xff1a;按照 左子树->根节点->右子树的顺序遍历二叉树 题目…

10款好用的开源 HarmonyOS 工具库

大家好&#xff0c;我是 V 哥&#xff0c;今天给大家分享10款好用的 HarmonyOS的工具库&#xff0c;在开发鸿蒙应用时可以用下&#xff0c;好用的工具可以简化代码&#xff0c;让你写出优雅的应用来。废话不多说&#xff0c;马上开整。 1. efTool efTool是一个功能丰富且易用…

java入门基础(一篇搞懂)

​ 如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论&#xff0c;感谢您的支持&#xff01;&#xff01;&#xff01; 首先给大家推荐比特博哥&#xff0c;java入门安装的JDk和IDEA社区版的安装视频 JDK安装与环境变量的配置 IDEA社区的安装与使…

多线程-初阶(1)

本节⽬标 • 认识多线程 • 掌握多线程程序的编写 • 掌握多线程的状态 • 掌握什么是线程不安全及解决思路 • 掌握 synchronized、volatile 关键字 1. 认识线程&#xff08;Thread&#xff09; 1.1 概念 1) 线程是什么 ⼀个线程就是⼀个 "执⾏流". 每个线…

数据在内存中的存储【上】

一.整型在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下面的内容&#xff1a; 整数的2进制表示方法有三种&#xff0c;即 原码、反码和补码 有符号的整数&#xff0c;三种表示方法均有符号位和数值位两部分&#xff0c;符号位都是用0表示"正"&#xff…

Java之队列

1. 概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性 特点&#xff1a; 队列具有先进先出FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾&#xff08;Tail/Rear&#xff09; 出队列&#xff1a;进…

Pikachu-Sql-Inject - 基于时间的盲注

基于时间的盲注&#xff1a; 就是前端的基于time 的盲注&#xff0c;什么错误信息都看不到&#xff0c;但是还可以通过特定的输入&#xff0c;判断后台的执行时间&#xff0c;从而确定注入。 mysql 里函数sleep() 是延时的意思&#xff0c;sleep(10)就是数据库延时10 秒返回内…

【C++】异常处理

目录 一、C语言中传统的异常处理方式&#xff1a; 二、C中的异常处理方式&#xff1a; 三、异常的使用 1、关于抛出与捕获&#xff1a; 2、关于异常的抛出和匹配&#xff1a; 3、异常的重新抛出&#xff1a; 4、异常安全&#xff1a; 5、异常规范&#xff1a; 四、异常…

idea 同一个项目不同模块如何设置不同的jdk版本

在IntelliJ IDEA中&#xff0c;可以为同一个项目中的不同模块设置不同的JDK版本。这样做可以让你在同一个项目中同时使用多个Java版本&#xff0c;这对于需要兼容多个Java版本的开发非常有用。以下是设置步骤&#xff1a; 打开项目设置&#xff1a; 在IDEA中&#xff0c;打开你…

Git 下载及安装超详教程(2024)

操作环境&#xff1a;Win 10、全程联网 一、什么是Git&#xff1f; Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 创立&#xff0c;用于有效、高速地处理从小到大的项目版本管理。Git 是目前世界上最流行的版本控制系统&#xff0c;被广泛用于软件开发中…

论文翻译 | Generated Knowledge Prompting for Commonsense Reasoning

摘要 整合外部知识是否有利于常识推理&#xff0c;同时保持预训练序列模型的灵活性&#xff0c;这仍然是一个悬而未决的问题。为了研究这个问题&#xff0c;我们开发了生成知识提示&#xff0c;它包括从语言模型生成知识&#xff0c;然后在回答问题时提供知识作为附加输入。我们…

TCP ---滑动窗口以及拥塞窗口

序言 在上一篇文章中我们介绍了 TCP 中的协议段格式&#xff0c;以及保证其可靠传输的重传机制&#xff0c;着重介绍了三次握手建立连接&#xff0c;四次挥手断开连接的过程(&#x1f449;点击查看)。  这只是 TCP 保证通信可信策略的一部分&#xff0c;现在让我们继续深入吧&…

盲拍合约:让竞拍更公平与神秘的创新解决方案

目录 前言 一、盲拍合约是什么&#xff1f; 二、盲拍合约工作原理 1、合约创建与初始化 2、用户出价&#xff08;Bid&#xff09; 3、出价结束 4、披露出价&#xff08;Reveal&#xff09; 5、处理最高出价 6、结束拍卖 7、退款与提款 三、解析盲拍合约代码…

02:(寄存器开发)流水灯/按键控制LED

寄存器开发 1、LED流水灯2、按键控制LED 1、LED流水灯 通过第一章的学习&#xff0c;我们已然知晓了LED的点亮和熄灭的方式&#xff0c;下面学习流水灯的制作流程。 流水灯呈现的样子&#xff1a;就是第一个LED灯点亮&#xff0c;延迟一段时间&#xff0c;第一个LED灯熄灭第二…