c++实现二叉搜索树(上)

news2025/1/12 22:51:08

 宝贝们,好久不见,甚是想念🤗小吉断更了差多有10多天,在断更的日子里,小吉也有在好好学习数据结构与算法,但是学的并不多而且学的并不是很认真。主要是中途笔记本屏出现问题了(这件事有点让小吉我没法好好沉下心来学习,而且不用电脑学起来有点费劲,不能边学边敲代码😖),换了个屏,小吉我现在是满血复活(啊哈哈哈),现在的我是看着新屏幕在写blog(着实很开兴🎉🎉🎉)
 没想到,小吉我又讲了这么多的废话(太激动了,实在是抱歉~),从这里开始就要进入我们今天的学习了(前面的废话大家可以不看,但从这开始就要好好看了哦)。
 今天我们要学习一种基础算法,也就是二叉搜索树,老规矩,在实现二叉搜索树之前,我们先来了解了解二叉搜索树是什么。

二叉搜索树的定义

二叉搜索树
1.树节点增加key属性,用来比较谁大谁小,key不可以重复
2.对于任意一个节点,它的key比左子树的key都大,同时也比右子树的key都小

善解人意的小吉猜很多小可爱们看到这些概念都很难一下子就理解了,接下来小吉画一张图,方便大家理解(比起上面👆的概念,小吉认为下面的图比较重要)
二叉搜索树
注:标的数值都是键值
最后,小吉来考考你们🧐,看看你们是否是真的了解了二叉搜索树,上图👆键值6的右子树的取值范围
(>6&&<7这个是答案哦~)

二叉搜索树的时间复杂度
(平均时间复杂度)O(logn) 对数时间
(最坏情况时间复杂度)O(n) 线性时间

(小吉不禁想到二分查找了,感觉二叉搜索树和二分查找有点莫名的相似,小吉我有出过和二分查找相关的博客,但没有总结过二分查找的知识点,看小可爱们的反馈吧,有需要小吉再出❤️)

二叉搜索树的实现大纲

get——查找键值对应的实值
min——查找最小键值对应的实值
max——查找最大键值对应的实值
put——存储键值和实值
successor——查找键值的前任(即前继节点)
predecessor——查找键值的后任(即后继节点)
deletednode——根据键值删除
范围查询:
myless——找<key的所有实值
mygreater——找>key的所有实值
mybetween——找>=key1且<=key2的所有实值

搭建基本框架

 二叉搜索树节点类(不同之处:小吉我设置的节点有键值(起索引作用)和实值,所有元素都会根据元素的键值自动排序)

class BSTnode
{
public:
	//初始化列表
	BSTnode(int key,string value):_key(key),_value(value),_left(nullptr),_right(nullptr) {}
public:
	int _key;//键值
	string _value;//实值
	BSTnode* _left;
	BSTnode* _right;
};

实现二叉搜索树方法的类

class BSTTree
{
public:
	BSTTree(BSTnode* root):_root(root) { }
public:
	BSTnode* _root;//根节点
};

创建二叉搜索树(方便后期测试)

BSTnode* buildTree()
{
	//创建根节点
	BSTnode* root = new BSTnode(4, "庄周");

	//创建左子树
	root->_left = new BSTnode(2, "东皇太一");
	root->_left->_left = new BSTnode(1, "小乔");
	root->_left->_right = new BSTnode(3, "大乔");

	//创建右子树
	root->_right = new BSTnode(6, "兰陵王");
	root->_right->_left = new BSTnode(5, "王昭君");
	root->_right->_right = new BSTnode(7, "百里守约");

	return root;
}

树

get——查找键值对应的实值

有两种实现方式,递归和非递归

思路:比较键值,以根节点为例,要找的键值比根节点的键值大,往右找;要找的键值比根节点的键值小,往左找;若相等,返回该节点的实值

递归实现,先实现一个递归查找的方法,再用get进行调用

string BSTTree::doGet(BSTnode* node, int key)
{
	if (node == nullptr)
	{
		return "没找到";//没找到
	}
	if (node->_key<key)
	{
		return doGet(node->_right, key);
	}
	else if (node->_key>key)
	{
		return doGet(node->_left, key);
	}
	else
	{
		return node->_value;
	}
}
string BSTTree:: get(int key)//查找键值对应的实值
	{
		return doGet(_root, key);
	}

非递归实现

string BSTTree::get2(int key)
{
	BSTnode* node = _root;
	while (node != nullptr)
	{
		if (node->_key > key)
		{
			node = node->_left;
		}
		else if (node->_key < key)
		{
			node = node->_right;
		}
		else
		{
			return node->_value;
		}
	}
	return "没找到";
}

min——查找最小键值对应的实值

思路:二叉搜索树的定义是对于一个任意节点它的左子树的一定比它小(针对键值_key而言),所以查找最小键值就要一直往左找,直到左子树为空,往左找可以分为递归和非递归两种方式

递归实现

string BSTTree::doMin(BSTnode* node)
{
	if (node == nullptr)
	{
		return "二叉树中没有节点";
	}
	if (node->_left == nullptr)
	{
		return node->_value;
	}
	return doMin(node->_left);
}
string BSTTree::min()//查找最小键值对应的实值
	{
		return doMin(_root);
	}

非递归实现

string BSTTree::min2()
{
	if (_root == nullptr)
	{
		return "二叉树没有节点";
	}
	BSTnode* node = _root;
	while (node->_left != nullptr)
	{
		node = node->_left;
	}
	return node->_value;
}

max——查找最大键值对应的实值

思路:和查找最小键值对应的实值思路差不多,要一直往右找,直到右子树为空

这里就只提供一种实现方式:非递归实现

string BSTTree::max()
{
	if (_root == nullptr)
	{
		return "二叉树中没有节点";
	}
	BSTnode* p = _root;
	while (p->_right != nullptr)
	{
		p = p->_right;
	}
	return p->_value;
}

put——存储键值和对应的实值

思路:分为两种情况,1)当提供的键值在树中存在,只用更新节点的实值即可 2)键值在树中不存在,就要新增节点(建立新的父子关系)
 遍历二叉搜索树,查找键值是否存在,并在查找的过程中用指针记录父节点,找到直接更新即可;没找到新增节点,并建立父子关系

代码实现

void BSTTree::put(int key, string value)
{
	BSTnode* node = _root;
	BSTnode* parent = nullptr;
	while (node != nullptr)
	{
		parent = node;
		if (node->_key < key)
		{
			node = node->_right;
		}
		else if (node->_key > key)
		{
			node = node->_left;
		}
		else
		{
			//key找到了,更新
			node->_value = value;
			return;
		}
	}
	//二叉树一开始就没有节点
	if (parent == nullptr)
	{
		_root = new BSTnode(key, value);
		return;
	}
	//key没有找到,新增
	if (parent->_key > key)//parent为新增节点的父节点
	{
		parent->_left = new BSTnode(key, value);
	}
	else
	{
		parent->_right = new BSTnode(key, value);
	}
}

 小吉的这篇blog就先讲到这了,二叉搜索树还没有讲完,怕讲太多各位小伙伴们不能很好的吸收理解(其实一次性讲完小吉会很累的🤫)
 学习的时间总是短暂的,这篇博客到这里就结束了,下一篇blog我们接着唠,期待一下小吉的下一篇blog吧,在小吉没有更新的日子里,希望大家不要忘了小吉哦❤️,也别忘了好好学习数据结构和算法(共勉💪)

最后的最后,创作不易,还望各位baby们多多支持🌹🌹🌹
(如有错,还望各位大大们多多指导😘)

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

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

相关文章

迅狐短视频矩阵管理系统核心功能

一、多平台管理&#xff1a;连接多个主流自媒体平台&#xff0c;满足多平台、多账号、多角色的协调需求 在现如今的多元化媒体环境中&#xff0c;一个优秀的内容创作者需要同时管理多个自媒体平台&#xff0c;并以不同的身份角色展现自己。迅狐短视频矩阵管理系统强大的多平台…

RPC(远程过程调用):技术原理、应用场景与发展趋势

摘要&#xff1a; RPC&#xff08;Remote Procedure Call&#xff09;是一种通信协议&#xff0c;用于实现跨网络的进程间通信。它提供了一种简单高效的方式&#xff0c;使得分布式系统中的不同组件能够像调用本地函数一样调用远程函数。本篇博客将介绍RPC的基本概念&#xff0…

kafka 快速上手

下载 Apache Kafka 演示window 安装 编写启动脚本,脚本的路径根据自己实际的来 启动说明 先启动zookeeper后启动kafka,关闭是先关kafka,然后关闭zookeeper 巧记&#xff1a; 铲屎官&#xff08;zookeeper&#xff09;总是第一个到&#xff0c;最后一个走 启动zookeeper call bi…

虚拟声卡实现音频回环

虚拟声卡实现音频回环 一、电脑扬声器播放声音路由到麦克风1. Voicemeeters安装设置2. 音频设备选择 二、回声模拟 一、电脑扬声器播放声音路由到麦克风 1. Voicemeeters安装设置 2. 音频设备选择 以腾讯会议为例 二、回声模拟 选中物理输入设备“Stereo Input 1”和物理输出设…

浅谈内联钩取原理与实现

前言 导入地址表钩取的方法容易实现但是存在缺陷&#xff0c;若需要钩取的函数不存在导入地址表中&#xff0c;那么我们就无法进行钩取&#xff0c;出现以下几种情况时&#xff0c;导入函数是不会存储在导入地址表中的。 延迟加载&#xff1a;当导入函数还没调用时&#xff0…

Rust 实战丨通过实现 json! 掌握声明宏

在 Rust 编程语言中&#xff0c;宏是一种强大的工具&#xff0c;可以用于在编译时生成代码。json! 是一个在 Rust 中广泛使用的宏&#xff0c;它允许我们在 Rust 代码中方便地创建 JSON 数据。 声明宏&#xff08;declarative macros&#xff09;是 Rust 中的一种宏&#xff0…

debug调试_以Pycharm为例

文章目录 作用步骤打断点调试调试窗口 作用 主要是检查逻辑错误&#xff0c;而非语法错误。 步骤 打断点 在需要调试的代码行前打断点&#xff0c;执行后会停顿在断点位置&#xff08;不运行&#xff09; 调试 右键“debug”&#xff0c;或者直接点击右上角的小虫子 调试…

2-2 基于matlab的变邻域

基于matlab的变邻域&#xff0c;含变惯性权重策略的自适应离散粒子群算法&#xff0c;适应函数是多式联运路径优化距离。有10城市、30城市、75城市三个案例。可直接运行。 2-2 路径规划 自适应离散粒子群算法 - 小红书 (xiaohongshu.com)

Vue基本使用-02

上节我们讲了什么是mvvm模型&#xff0c;以及我们vue的一些常用指令&#xff0c;今天给大家讲一下vue的基本使用&#xff0c;在将之前我们需要重点讲解我们的一个指令&#xff0c;v-model指令 v-model v-model 可以在组件上使用以实现双向绑定,什么是双向绑定呢?意思就是当我们…

【Ubuntu双系统】两块硬盘分别安装系统,一块硬盘安装Ubuntu 一块安装Windows

【Ubuntu双系统】两块硬盘分别安装双系统&#xff0c;一块硬盘安装Ubuntu 一块安装Windows 前言安装Ubuntu前置操作安装过程参考文献 前言 机器情况&#xff1a;两块1T的硬盘&#xff0c;其中一块已安装Windows 11现需在另一块硬盘上安装Ubuntu&#xff0c;该硬盘还未初始化Ub…

SQL聚合函数---汇总数据

此篇文章内容均来自与mysql必知必会教材&#xff0c;后期有衍生会继续更新、补充知识体系结构 文章目录 SQL聚集函数表&#xff1a;AGV()count()根据需求可以进行组合处理 max()min()max&#xff08;&#xff09;、min&#xff08;&#xff09;、avg&#xff08;&#xff09;组…

Mac下载了docker,在终端使用docker命令时用不了

问题&#xff1a;在mac使用docker的时候&#xff0c;拉取docker镜像失败 原因&#xff1a;docker是需要用app使用的 &#xff0c;所以在使用的时候必须打开这个桌面端软件才可以在终端上使用docker命令&#xff01;&#xff01;&#xff01;

【PL理论】(21) 函数式语言:支持匿名函数 fun x → E | 设计递归函数 | 支持递归函数:let rec ...

&#x1f4ad; 写在前面&#xff1a;本章我们将讲解支持匿名函数&#xff0c;先回顾一下 F# 语言表示函数的方法&#xff0c;然后引出它。随后我们讲解一下如何设计递归函数&#xff0c;最后让我们的 F- 语言支持递归函数。 目录 0x00 回顾&#xff1a;F# 语言 0x01 支持匿名…

深度学习笔记: 最详尽Airbnb租赁搜索排名设计

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; Airbnb租赁搜索排名 1. 问题陈述 Airbnb用户在特定地点搜索可用房源。系统应在搜索结果中对多个房源进…

Qt飞机大战小游戏

Gitee地址 &#xff1a;plane-game: 基于Qt的飞机大战小游戏 GitHub地址&#xff1a; https://github.com/a-mo-xi-wei/plane-game

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…

图片导入AutoCAD建立草图—CAD图像导入插件

插件介绍 CAD图像导入插件可将PNG&#xff0c;JPG等格式图片导入到AutoCAD软件内建立图像边缘的二维线条模型。插件可以提取图像黑色或白色区域的边界&#xff0c;并可绘制原状边界或平滑边界两种样式。 模型说明 边界提取&#xff0c;黑色或白色边界的提取根据原图类型选择…

【云原生| K8S系列】Kubernetes Daemonset,全面指南

Kubernetes中的DaemonSet是什么? Kubernetes是一个分布式系统&#xff0c;Kubernetes平台管理员应该有一些功能可以在所有节点上运行特定于平台的应用程序。例如&#xff0c;在所有Kubernetes节点上运行日志代理。 这就是Daemonset发挥作用的地方。 Daemonset是一个原生的K…

查询满足条件的元组-WHRER子句(运算符、BETWEEN 、LIKE、IN、NULL)

一、WHERE子句&#xff08;筛选出使选择表达式为真的元组&#xff09; 1、SELECT-FROM子句可以实现数据的查询&#xff08;会查询出所有元组&#xff09;&#xff0c;加上WHERE子句之后可以实现数据的筛选&#xff08;会查询出满足条件的元组&#xff09; SELECT 【ALL|DISTI…

windows 下 基于 WSL2安装DeepSpares进行YOLOV8 v5 的加速推理

文章大纲 简介软硬件限制安装安装 WSL2 基础环境WSL2 手动安装安装 miniconda 环境本地USB 摄像头使用:Windows 无延迟视频流本地USB 摄像头使用:WSL2 挂载 本地 USB 摄像头WSL2更新报错: 离线安装 wsl --update安装 DeepSpares测试打开本地USB 摄像头进行测试测试结果参考文…