map和set(一)

    首先模拟一下key形式类 使用的结构是搜索二叉树  结点中有左孩子和右孩子  还有一个存储的值

	template <class K>
	struct BSTnode//搜索二叉树不支持修改  中序遍历是有序的
	{

		K _key;
		BSTnode<K>* _left;
		BSTnode<K>* _right;

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

这里二叉树代码在之前有更详细的 也有测试代码 就不去复制了  

主要功能有四个  删除 插入 遍历  查找  

 

     模拟一下key/value形式类  使用的结构是搜索二叉树   每一个节点中有左孩子和右孩子 还有一个key 和一个value  当我们找到可以key之后 也就找到了对应的value

template <class K, class V>
struct BSTnode//搜索二叉树不支持修改  中序遍历是有序的
{

	K _key;
	V _value;
	BSTnode<K, V>* _left;
	BSTnode<K, V>* _right;

	BSTnode(const K& key, const V& value)

		:_key(key)
		, _value(value)
		, _left(nullptr)
		, _right(nullptr)
	{}
};

之后二叉树的功能有插入 删除  查找 遍历   这其中只有insert 需要修改  既要插入value 也要插入key  但对于删除 查找 遍历 只要有key就可以完成 所以就不需要改变

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

这里通过一段string类型的进行测试

int main()
{
	keyvalue::BSTree <string, string> tt;
	tt.insert("left","左边");
	tt.insert("right", "右边");
	tt.insert("insert", "插入");
	tt.insert("string", "字符串");

	string str;
	while (cin >> str)
	{
		auto ret = tt.find(str);
		if (ret)
		{
			cout << "->" << ret->_value << endl;
		}
		else
		{
			cout << "无此单词 请重新输入" << endl;
		}
	}
	//tt.insert();

	return 0;
}

通过查找key 就可以确定对应的存储value内容  非常方便   这里最后使用的是ctrl+z来结束程序执行

  这里使用到了 operator>>(string)这个函数的返回值istream 会被operator bool 转换成bool值来进行判断是否结束程序  而当我们输入ctrl+z  就会转换成bool值false 这样就会结束程序

    首先模拟一下key形式类 使用的结构是搜索二叉树  结点中有左孩子和右孩子  还有一个存储的值

	template <class K>
	struct BSTnode//搜索二叉树不支持修改  中序遍历是有序的
	{

		K _key;
		BSTnode<K>* _left;
		BSTnode<K>* _right;

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

这里二叉树代码在之前有更详细的 也有测试代码 就不去复制了  

主要功能有四个  删除 插入 遍历  查找  

     模拟一下key/value形式类  使用的结构是搜索二叉树   每一个节点中有左孩子和右孩子 还有一个key 和一个value  当我们找到可以key之后 也就找到了对应的value

template <class K, class V>
struct BSTnode//搜索二叉树不支持修改  中序遍历是有序的
{

	K _key;
	V _value;
	BSTnode<K, V>* _left;
	BSTnode<K, V>* _right;

	BSTnode(const K& key, const V& value)

		:_key(key)
		, _value(value)
		, _left(nullptr)
		, _right(nullptr)
	{}
};

之后二叉树的功能有插入 删除  查找 遍历   这其中只有insert 需要修改  既要插入value 也要插入key  但对于删除 查找 遍历 只要有key就可以完成 所以就不需要改变

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

这里通过一段string类型的进行测试

int main()
{
	keyvalue::BSTree <string, string> tt;
	tt.insert("left","左边");
	tt.insert("right", "右边");
	tt.insert("insert", "插入");
	tt.insert("string", "字符串");

	string str;
	while (cin >> str)
	{
		auto ret = tt.find(str);
		if (ret)
		{
			cout << "->" << ret->_value << endl;
		}
		else
		{
			cout << "无此单词 请重新输入" << endl;
		}
	}
	//tt.insert();

	return 0;
}

通过查找key 就可以确定对应的存储value内容  非常方便   这里最后使用的是ctrl+z来结束程序执行

  这里使用到了 operator>>(string)这个函数的返回值istream 会被operator bool 转换成bool值来进行判断是否结束程序  而当我们输入ctrl+z  就会转换成bool值false 这样就会结束程序

这里的key/value除了可以运用在字典序中 还可以运用在计数上

int main()
{
	// 统计水果出现的次数
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
   "苹果", "香蕉", "苹果", "香蕉" };
	keyvalue::BSTree<string, int> countTree;
	for (const auto& str : arr)
	{
		// 先查找水果在不在搜索树中
		// 1、不在,说明水果第一次出现,则插入<水果, 1>
		// 2、在,则查找到的节点中水果对应的次数++
		//BSTreeNode<string, int>* ret = countTree.Find(str);
		auto ret = countTree.find(str);
		if (ret == NULL)
		{
			countTree.insert(str, 1);
		}
		else
		{
			ret->_value++;
		}
	}
	countTree.inorder();

	return 0;
}

 接下来我们写一下二叉树的析构

    ~BSTree()
{
	destroy(_root);
	_root = nullptr;
}

void destroy(node*root)
	{
		if (root == nullptr)
			return;
		destroy(root->_left);
		destroy(root->_right);
        delete root;
	}

这里需要用到destroy函数这是因为析构函数是没有参数的 而二叉树的析构有需要用到参数 所以嵌套了一个destroy函数  这里使用的是递归  先销毁左边  在销毁右节点  最后销毁跟节点

接下来写一下 拷贝构造 

由于我们现在没有写拷贝构造 使用的是浅拷贝 会出问题

int main()
{
	keyvalue::BSTree <string, string> tt;
	tt.insert("left","左边");
	tt.insert("right", "右边");
	tt.insert("insert", "插入");
	tt.insert("string", "字符串");
	keyvalue::BSTree<string, string> t(tt);
	return 0;
}

这时代码是会崩溃的

BSTree(const BSTree<K,V>& t)
{
	_root = copy(t._root);
}	
node* copy(node* root)
	{
		if (root == nullptr)
		{
			return 0;
		}
			node* newroot = new node(root->_key, root->_value);
		     newroot->_left = copy(root->_left);
		     newroot->_right = copy(root->_right);

			return newroot;
		
	}

 这里同样需要传参  所以进行了嵌套copy函数  这里如果二叉树为空就返回  如果不为空 开始拷贝  从根节点开始首先赋值 之后链接对应左右孩子 这里左右孩子的拷贝通过递归完成

写完成之后运行会出问题

这是因为没有默认构造函数 这里我们写一个比较快捷的方式

	BSTree() = default;

 

这样拷贝构造就可以正常运行了

 

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

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

相关文章

网络资源模板--Android Studio 实现记事本App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的记事本App 二、项目测试环境 三、项目详情 首页 显示笔记列表&#xff1a;使用 ListView 显示从数据库中查询到的笔记内容。搜索功能&#xff…

web-105linux权限提升

rsync未授权本地覆盖 Rsync 是 linux 下一款数据备份工具&#xff0c;默认开启 873 端口 https://vulhub.org/#/environments/rsync/common/ 借助 Linux 默认计划任务调用/etc/cron.hourly&#xff0c;利用 rsync 连接覆盖 前提条件就是需要知道rsync的密码或者存在未授权 -提…

Java微信支付接入(6) - API V3 Native 支付通知API

官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml 通知规则&#xff1a;用户支付完成后&#xff0c;微信会把相关支付结果和用户信息发送给商户&#xff0c;商户需要接收处理该消息&#xff0c;并返回应答。对后台通知交互时&#xff0c…

如何解决 Vim 中的 “E212: Can‘t open file for writing“ 错误:从编辑到权限管理(sudo)

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

第十五届蓝桥杯C++B组省赛

文章目录 1.握手问题解题思路1&#xff08;组合数学&#xff09;解题思路2&#xff08;暴力枚举&#xff09; 2.小球反弹做题思路 3.好数算法思路&#xff08;暴力解法&#xff09;---不会超时 4.R格式算法思路 5.宝石组合算法思路---唯一分解定理 6.数字接龙算法思路----DFS 7…

TinyOS 点对基站通信

文章目录 一、前言1.1 发包的BlinkToRadio的数据包格式 二、混淆基站源码分析2.1 Makefile2.2 组件连接2.3 主逻辑代码 一、前言 1.1 发包的BlinkToRadio的数据包格式 如下&#xff0c;注意&#xff1a;AM层类型(1byte)即handlerID使可以在组件中修改的。 二、混淆基站源码…

uniapp学习(004-1 组件 Part.2生命周期)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第31p-第p35的内容 文章目录 组件生命周期我们主要使用的三种生命周期setup(创建组件时执行)不可以操作dom节点…

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idchinaFlag 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-ce…

python异常检测 - 随机离群选择Stochastic Outlier Selection (SOS)

python异常检测 - Stochastic Outlier Selection (SOS) 前言 随机离群选择SOS算法全称stochastic outlier selection algorithm. 该算法的作者是jeroen janssens. SOS算法是一种无监督的异常检测算法. 随机离群选择SOS算法原理 随机离群选择SOS算法的输入: 特征矩阵(featu…

【代码】集合set

哈喽大家好&#xff0c;我是学霸小羊&#xff0c;今天来讲一讲集合&#xff08;set&#xff09;。 在数学上&#xff0c;集合长这样&#xff1a; 那今天就来讲一讲编程上的集合。 集合的定义&#xff1a;把一些元素按照某些规律放在一起&#xff0c;就形成了一个集合。比如说…

stm32单片机个人学习笔记10(TIM编码器接口)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

论文笔记:Template-Based Named Entity Recognition Using BART

论文来源&#xff1a;ACL 2021 Finding 论文链接&#xff1a;https://aclanthology.org/2021.findings-acl.161.pdf 论文代码&#xff1a;GitHub - Nealcly/templateNER: Source code for template-based NER 笔记仅供参考&#xff0c;撰写不易&#xff0c;请勿恶意转载抄袭…

D35【python 接口自动化学习】- python基础之输入输出与文件操作

day35 文件合并 学习日期&#xff1a;20241012 学习目标&#xff1a;输入输出与文件操作&#xfe63;-47 如何使用python合并多个文件&#xff1f; 学习笔记&#xff1a; 合并文件需求分析 合并两个文件 代码实现 # 合并两个文件 with open(demo1.txt) as f1:file_data_1f…

机器学习(10.7-10.13)(Pytorch LSTM和LSTMP的原理及其手写复现)

文章目录 摘要Abstract1 LSTM1.1 使用Pytorch LSTM1.1.1 LSTM API代码实现1.1.2 LSTMP代码实现 1.2 手写一个lstm_forward函数 实现单向LSTM的计算原理1.3 手写一个lstmp_forward函数 实现单向LSTMP的计算原理总结 摘要 LSTM是RNN的一个优秀的变种模型&#xff0c;继承了大部分…

鸿蒙--知乎评论

这里我们将采用组件化的思想进行开发 在开发中默认展示的是首页也就是 pages/Index.ets页面 这里存放的是所有页面的配置文件,类似与uniapp中的pages.json 如果我们此时要更改默认显示Zh

jmeter入门: 安装

前提&#xff1a; 安装jdk1.8&#xff0c; 并设置java_home 和path环境变量。 ​​​​​​1. download Apache JMeter - Download Apache JMeter 2. 解压jmeter包 3. 安装插件Install :: JMeter-Plugins.org 下载jar包&#xff0c;放到lib/ext目录 4. 打开jmeter &#xff0…

安装Node.js环境,安装vue工具

一、安装Node.js 去官方网站自行安装自己所需求的安装包 这是下载的官方网站 下载 | Node.js 中文网 给I accept the terms in the License Agreement打上勾然后点击Next 把安装包放到自己所知道的位置,后面一直点Next即可 等待它安装好 然后winr打开命令提示符cmd 二、安装…

解决报错:Invalid number of channels [PaErrorCode -9998]

继昨天重装了树莓派系统后&#xff0c;今天开始重新安装语音助手。在测试录音代码时遇到了报错“Invalid number of channels [PaErrorCode -9998]”&#xff0c;这是怎么回事&#xff1f; 有人说这是因为pyaudio没有安装成功造成的。于是&#xff0c;我pip3 install –upgrad…

难点:Linux 死机定位(进程虚拟地址空间耗尽)

死机定位(进程虚拟地址空间耗尽) 一、死机现象 内存富裕,但内存申请失败。 死机时打印: 怀疑是: 1、内存碎片原因导致。 2、进程虚拟地址空间耗尽导致。 3、进程资源限制导致。 二、内存碎片分析 1、理论知识:如何分析内存碎片化情况 使用 /proc/buddyinfo: /proc/…

数据结构-串

串的定义 串的操作 字符集编码 串的顺序存储 串的链式存储 模式匹配