【Cpp】手撕搜索二叉树(KV模型)

news2025/4/3 13:24:39

文章目录

  • 二叉搜索树的应用
  • 搜索二叉树(KV模型)代码:
  • 二叉搜索树的性能分析

二叉搜索树的应用

  1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。
    比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:
    以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
    在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
  2. KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。该种方式在现实生活中非常常见:
    比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word, chinese>就构成一种键值对;
    再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word, count>就构成一种键值对

搜索二叉树(KV模型)代码:

由于我的上一篇文章详细介绍了K模型的书写,KV模型与K模型的代码书写方面是别无二致的,只需要对于增操作多加一个value值即可.
这里就直接贴上代码了,有不懂的部分请移步上一篇文章:

namespace key_value
{
#pragma once

	// BinarySearchTree -- BSTree
	// SearchBinaryTree


	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode<K, V>* _left;
		BSTreeNode<K, V>* _right;
		K _key;
		V _value;


		BSTreeNode(const K& key, const V& value)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
			, _value(value)
		{}
	};

	template<class K, class V>
	class BSTree
	{
		typedef BSTreeNode<K, V> Node;
	public:

		bool Insert(const K& key, const V& value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key, value);
				return true;
			}

			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;
				}
			}

			cur = new Node(key, value);
			// 链接
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}

			return true;
		}

		Node* 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 cur;
				}
			}

			return nullptr;
		}

		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
				{
					// 删除
					// 1、左为空
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}

						delete cur;

					} // 2、右为空
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}

						delete cur;
					}
					else
					{
						// 找右树最小节点替代,也可以是左树最大节点替代
						Node* pminRight = cur;
						Node* minRight = cur->_right;
						while (minRight->_left)
						{
							pminRight = minRight;
							minRight = minRight->_left;
						}

						cur->_key = minRight->_key;

						if (pminRight->_left == minRight)
						{
							pminRight->_left = minRight->_right;
						}
						else
						{
							pminRight->_right = minRight->_right;
						}

						delete minRight;
					}

					return true;
				}
			}

			return false;
		}


		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	protected:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

			_InOrder(root->_left);
			cout << root->_key << ":" << root->_value << endl;
			_InOrder(root->_right);
		}
	private:
		Node* _root = nullptr;
	};
}

二叉搜索树的性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。
最好情况与最坏情况

但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:
最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为: l o g 2 N log_2 N log2N
最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为: N 2 \frac{N}{2} 2N
问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,二叉搜索树的性能都能达到最优?那么我后续即将介绍的AVL树和红黑树就可以上场了。

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

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

相关文章

水果FL Studio21最新中文完整版下载更新及内容介绍

简单总结一下&#xff0c;本次小版本更新最重要的内容&#xff0c;我个人认为是对于M1芯片的适配。其余的比如EQ2&#xff0c;3x这些我们很熟悉的插件虽说也有更新&#xff0c;但是估计并没有特别大的改动。我个人的话会先放一段时间&#xff0c;等下次有其他更让我感兴趣的内容…

吃透SpringMVC面试八股文

说说你对 SpringMVC 的理解 SpringMVC是一种基于 Java 的实现MVC设计模型的请求驱动类型的轻量级Web框架&#xff0c;属于Spring框架的一个模块。 它通过一套注解&#xff0c;让一个简单的Java类成为处理请求的控制器&#xff0c;而无须实现任何接口。同时它还支持RESTful编程…

【智能电网】智能电网中针对DOS和FDIA的弹性分布式EMA(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

burpsuite的基本使用

一&#xff0c;Proxy&#xff08;代理&#xff09; 目录 一&#xff0c;Proxy&#xff08;代理&#xff09; 1.1 intercept &#xff08;拦截&#xff09; 1.2 HTTP history&#xff08;HTTP历史记录&#xff09; 1.3 WebSockets history 1.4 options&#xff08;选项&am…

转换CAJ到PDF: 教你如何转换这两种文件格式

在现代信息化社会中&#xff0c;我们常常需要处理各种文件格式&#xff0c;例如常见的文本文档、PDF、图片、视频等等。其中&#xff0c;学术界或者专业人士常常会接触到一种叫做CAJ格式的文件&#xff0c;而这个格式在阅读、编辑以及分享方面可能存在一些限制。为了解决这个问…

影响LED显示屏使用的因素

LED显示屏和其他物品一样&#xff0c;在使用中不免遇到这样或那样的问题。在使用LED显示屏的时候&#xff0c;可能会因散热设计、混灯八个问题&#xff0c;导致困难或影响LED显示屏的使用。而为能使LED显示屏的后期使用效能稳定&#xff0c;首先要做的就是预防它的老化。下面为…

Python OpenCV3 计算机视觉秘籍:6~9

原文&#xff1a;OpenCV 3 Computer Vision with Python Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&…

一文搞懂新型IO调度器BFQ简介

Linux io调度器有很多种&#xff0c;大多数调度器都经受住了各种市场环境的长时间验证&#xff0c;稳定性、性能得到各种用户的认可&#xff0c;但新的调度器依然展露头角&#xff0c;在4.12内核中出现了一个新的bfq调度器&#xff0c;这个调度器将取代曾经的辉煌的cfq调度器。…

Python3使用sys.argv和os.system 从一个程序调用另一个程序,并将参数传递

由于实验需要&#xff0c;需要从A.py 调用另一个B.py&#xff0c;并将A.py中的参数mean、max、min三个值传递给B。 这里参考了其他人的文章 http://t.csdn.cn/cQKio http://t.csdn.cn/QNqml http://t.csdn.cn/yEJeD 参考其他人的程序&#xff0c;发现其实很简单&#xff0c;…

ctfshow web入门代码审计 web301-305

1.web301 共有这几个文件 #checklogin.php <?php error_reporting(0); session_start(); require conn.php; $_POST[userid]!empty($_POST[userid])?$_POST[userid]:""; $_POST[userpwd]!empty($_POST[userpwd])?$_POST[userpwd]:""; $username$_PO…

LLVM编译器后端比较功能的添加

1.动机 从机器层面上来看&#xff0c;控制流类的跳转指令分为无条件跳转和有条件跳转&#xff0c;无条件跳转 JMP&#xff0c;有条件跳转 JEQ、JNE、JLT、JGT、JLE、JGE&#xff0c;这部分指令是需要通过检查 condition code &#xff08;SW 寄存器&#xff09;来决定跳转条件&…

解析基于Pytorch的残差神经网络(ResNet18模型),并使用数据集CIFAR10来进行预测与训练

解析基于Pytorch的残差神经网络&#xff08;ResNet18模型&#xff09;&#xff0c;并使用数据集CIFAR10来进行预测与训练 1.0、什么是残差神经网络 注&#xff1a;本人才疏学浅&#xff0c;如有纰漏&#xff0c;请不吝赐教 残差神经网络其实是与卷积神经网络分不开的&#x…

Java项目无法启动排查

Java项目无法启动排查 1.启动服务发现 无法写入日志也无法启动项目2.df查看磁盘占用情况 、free -h查看内存占用、top查看CPU使用率负载率3.此时磁盘满4.清理磁盘5.定时任务 1.启动服务发现 无法写入日志也无法启动项目 2.df查看磁盘占用情况 、free -h查看内存占用、top查看C…

计及源荷不确定性的综合能源生产单元运行调度与容量配置优化研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

java贸易企业工作信息管理与利润返现系统sxA5进销存程序

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1 课题背景 1 1.2 研究现状 1 本章小结 1 第2章 可行性分析 2 2.1 经济可行性 2 2.2 技术可行性 2 2.3 操作可行性 2 2.4 业务流程分析 3 本章小结 3 第3章 需求分析 4 3.1 需求分析 4 …

数据库基础篇 《3. 基本的SELECT语句》

目录 1. SQL概述 1.1 SQL背景知识 1.2 SQL语言排行榜 1.3 SQL 分类 2. SQL语言的规则与规范 2.1 基本规则 2.2 SQL大小写规范 &#xff08;建议遵守&#xff09; 2.3 注释 2.4 命名规则&#xff08;暂时了解&#xff09; 2.5 数据导入指令 3. 基本的SELECT语句 3.0…

【攻城狮计划】Renesas RA2E1 运行 命名

&#x1f6a9;WRITE IN FRONT&#x1f6a9; &#x1f50e;介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四"&#x1f50e;&#x1f3c5;荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星TOP10…

法大大合同批量下载

1.测试需求 法大大网上80万合同需要下载下来 其实总共1392392页,20885871万条合同数据要下载下来的 2.测试需求分析与验证 2.1调通接口,取到合同列表页信息 遇到的问题: 登录页面有图形验证码,不好处理 解决: 手动登录后用已经有的cookie,如果超时需要重新登录抓取co…

ChatGPT闲谈——火出圈的为什么是 OpenAI?

ChatGPT 走入大众视野之后&#xff0c;AIGC 行业迎来了爆发&#xff0c;尤其是上个月&#xff0c;仿佛每一天都可能是「历史性」的一天。 现在各大网站已经有非常多的优秀创作者进行总结和分析&#xff0c;都是值得一阅的好文。今天本文也分享了关于ChatGPT的看法&#xff0c;有…

顺序表—C语言实现数据结构

本期带大家一起来用C语言代码实现顺序表&#x1f308;&#x1f308;&#x1f308; 文章目录 一、顺序表的概念✅二、顺序表的结构✅三、顺序表的实现&#xff08;动态顺序表&#xff09;✅一、&#x1f536;定义顺序表结构体&#x1f536;二、&#x1f536;接口的实现&#x1…