【C++】如何用一棵红黑树同时封装出set与map

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》

🌝每一个不曾起舞的日子,都是对生命的辜负


目录

前言

1.红黑树模板参数的控制

2.红黑树节点的定义 

3.pair的比较规则引出红黑树仿函数设计

4.红黑树的正向迭代器 

4.1迭代器的定义 

4.2迭代器的构造 

4.3重载解引用操作符 * 

4.4重载箭头操作符 -> 

4.5重载 == 和 != 操作符 

4.6重载 ++、-- 操作符 

5.红黑树的反向迭代器

6.完整代码

RBTree.h

MySet.h

MyMap.h


前言

在之前的学习中,我们了解到set中存储的一般为键K即可,而map存储的一般都是键值对KV,也就是说他们结构是不同的,那么我们如何才能用一颗红黑树同时封装出set与map两种容器呢?

简单的说就是模板的使用,对于set存储的<K,K>,对于map存储的是<K,pair<K,V>>;

那么红黑树我们就可以使用模板,比如RBTree<K,T>,T就是这个模板类,当set使用时就是K,当map使用时就是pair。

那么接下来我们具体地来研究下STL库中是怎样实现的,并且进行模拟实现。


欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。 

=========================================================================

GITEE相关代码:🌟樊飞 (fanfei_c) - Gitee.com🌟

=========================================================================


1.红黑树模板参数的控制

template<class K, class T>
class RBTree

那么对于set:

template<class K>
class set
{
public:
	//...
private:
	RBTree<K, K> _t;
};

对于map:

template<class K, class V>
class map
{
public:
	//...
private:
	RBTree<K, pair<K, V>> _t;
};

即:


 思考:既然对于map来说pair中有K,那么是不是可以将第一个模板参数省略呢?

  • 对于set容器来说:可以,因为set传入红黑树的第二个参数与第一个参数是一样的;
  • 对于map容器来说:不行,因为map容器所提供的接口当中有些是只要求给出键值Key的,比如find和erase。

2.红黑树节点的定义 

//红黑树结点的定义
template<class T>
struct RBTreeNode
{
	//三叉链
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	//存储的数据
	T _data;

	//结点的颜色
	int _col;

	//构造函数
	RBTreeNode(const T& data)
		: _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _data(data)
		, _col(RED)
	{}
};

对于模板参数T来说,set使用就是K,map使用就是pair<K,V>,对应着set与map中节点存储的数据类型。


3.pair的比较规则引出红黑树仿函数设计

红黑树是一棵二叉搜索树,所以当我们寻找插入位置或者查找时一定会比较节点值之间的大小。

新插入节点值小于当前节点值,就往左走;

新插入节点值大于当前节点值,就往右走;

这是之前学习二叉搜索树最基本的特性,那么问题来了,对于map而言,节点值存储的是pair<K,V>,可是pair是依据什么来决定自身的大小呢?first?second?还是什么?

我们来看一下STL库中对pair比较大小的定义:

可我们期望的比较规则是这样么?

很明显不是,我们期望的是set与map都只依据Key来比较大小。

那么我们就需要想办法构造一个我们自己比较的方式出来。

首先比较的是Key,所以我们需要想办法取出Key,对于set而言那就是Key,对于map而言是pair的first,所以我们可以在红黑树中设计仿函数来统一设计,然后在set和map中具体实现即可。

set:

template<class K>
class set
{
	//仿函数
	struct SetKeyOfT
	{
		const K& operator()(const K& key) //返回键值Key
		{
			return key;
		}
	};
public:
	//...
private:
	RBTree<K, K, SetKeyOfT> _t;
};

map:

te
评论 82
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_FF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值