用红黑树实现map和set

主要是对模板的理解

首先对map封装

map是一种KV模型,在传参时,需要用pair将两个参数耦合,创建了一个类型,而set只需要传一个key值,所有需要统一接口。

原来传参的模板为

map--> RBTree<K,V,OfKV>       //  这里的OfKV也是用于统一接口
set-->RBTree<K,OfKV>

这样他们的接口不统一

统一的模板

在map类中 :RBTree<K, pair<K, V>, OfKV> _map;       //   由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
在set类中:RBTree<K, K, OfKV> _set;   

//  这样就构成了统一的模板个数
//  再将pair<K,V>  和  K  统一处理为KV类型
RBTree的模板:template<K,KV,OfKV>

节点结构体

template<class KV>
struct RBTreeNode
{
	RBTreeNode* _left;
	RBTreeNode* _right;
	RBTreeNode* _parent;
	KV _kv;
	Color _color;
	RBTreeNode(const KV& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _color(RED)
		,_kv(kv)
	{
	}
};

通过一个_kv就完成了赋值,对于map类型,KV就是pair<K,V>,key就是_kv的first,value就是_kv的second。对于set类型,KV就是K,_kv就代表key。

那么RBTree在不知道类型的情况下,是如何获取key进行比较的呢?

这时候,OfKV就发挥了作用,OfKV实际上是一个仿函数,在RBTree类中实例化。调用存在set类和map类中各自的函数获取key值。

用结构体创建一个新的类型,再将该类型作为模板传到RBTree类中实例化,调用函数获取键值。

	struct MakeKeyOfT        //    用仿函数,获取键值,为了与map一致,也写一个仿函数,形成统一接口
	{
		const K& operator()(const K& k)
		{
			return k;
		}
	};
	MakeKeyOfT koft;  //实例化
	struct MakeKeyOfT        //    用仿函数,获取键值
	{
		const K& operator()(const pair<K, V>& kv)
		{
			return kv.first;
		}
	};

接下来就是迭代器

迭代器是由一个红黑树节点和一些成员函数构成,迭代器的目的就是遍历,获取数据,而获取的数据都是KV类型的,因为_node的成员变量就是kv。

模板也只需要template<class KV>

template<class KV>
class RBTiterator
{
	typedef RBTreeNode<KV> RBTreeNode;
	typedef RBTiterator<KV> iterator;
public:
	RBTreeNode* _node;
	RBTiterator(RBTreeNode* node=nullptr)
		:_node(node)
	{ }
	KV& operator*()
	{
		return _node->_kv;
	}

	KV* operator->()
	{
		return &_node->_kv;
	}

	iterator& operator++()          //   前置++
	{
		if (_node->_right)   //  右子树非空,找右子树最左节点
		{
			RBTreeNode* subR = _node->_right;
			while(subR->_left)
			{
				subR = subR->_left;
			}
			_node = subR;
		}
		else      //  右子树为空
		{
			// 往回找祖先节点
			RBTreeNode* parent = _node->_parent;
			while (parent && _node == parent->_right)
			{
				_node = parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}

	bool operator!=(iterator it)
	{
		return _node != it._node;
	}
};

map的operator[]重载函数

	V& operator[](const K& k)
	{
		pair<iterator, bool> ret = _map.Insert(make_pair(k, V()));     //  V() 默认为0或空
		{
			return ret.first->second;
		}
	}


	pair<iterator,bool> Insert(const pair<K,V>& kv)
	{
		return _map.Insert(kv);
	}

源码

// .h


#pragma once
#include<iostream>
#include<utility>
using namespace std;

enum Color
{
	RED,
	BLACK
};
template<class KV>
struct RBTreeNode
{
	RBTreeNode* _left;
	RBTreeNode* _right;
	RBTreeNode* _parent;
	KV _kv;
	Color _color;
	RBTreeNode(const KV& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _color(RED)
		,_kv(kv)
	{
	}
};


template<class KV>
class RBTiterator
{
	typedef RBTreeNode<KV> RBTreeNode;
	typedef RBTiterator<KV> iterator;
public:
	RBTreeNode* _node;
	RBTiterator(RBTreeNode* node=nullptr)
		:_node(node)
	{ }
	KV& operator*()
	{
		return _node->_kv;
	}

	KV* operator->()
	{
		return &_node->_kv;
	}

	iterator& operator++()          //   前置++
	{
		if (_node->_right)   //  右子树非空,找右子树最左节点
		{
			RBTreeNode* subR = _node->_right;
			while(subR->_left)
			{
				subR = subR->_left;
			}
			_node = subR;
		}
		else      //  右子树为空
		{
			// 往回找祖先节点
			RBTreeNode* parent = _node->_parent;
			while (parent && _node == parent->_right)
			{
				_node = parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}

	bool operator!=(iterator it)
	{
		return _node != it._node;
	}
};



template<class K, class KV, class KOfT>
class RBTree
{
public:
	typedef RBTreeNode<KV> RBTreeNode;
	typedef RBTiterator<KV> iterator;       //    KV可以是K也可以是K V的pair<K,V>
 public:
	RBTree()
		:_node(nullptr)
	{
	}

	 iterator begin()
	{
		RBTreeNode* subL = _node;
		while (subL->_left)
		{
			subL = subL->_left;
		}
		return iterator(subL);
	}

	 iterator end()
	{
		return iterator(nullptr);
	}


	pair<iterator,bool> Insert(const KV& kv)
	{
		if (_node == nullptr)
		{
			_node = new RBTreeNode(kv);
			_node->_color = BLACK;
			return make_pair(iterator(_node), true);    
		}
		KOfT koft;      //  用于获取键值
		const K& key = koft(kv);

		RBTreeNode* cur = _node;
		RBTreeNode* parent = _node;
		while (cur)
		{
			if (key < koft(cur->_kv))
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (key > koft(cur->_kv))
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return make_pair(iterator(cur), false);
			}
		}

		if (key < koft(parent->_kv))
		{
			parent->_left = new RBTreeNode(kv);
			parent->_left->_parent = parent;
			parent->_left->_color = RED;
			cur = parent->_left;
		}
		if (key > koft(parent->_kv))
		{
			parent->_right = new RBTreeNode(kv);
			parent->_right->_parent = parent;
			parent->_right->_color = RED;
			cur = parent->_right;
		}

		RBTreeNode* newinsert = cur;     //  记录插入的节点,以便返回

		while (cur != _node && parent != _node)
		{
			if (parent->_color == BLACK)
			{
				return make_pair(iterator(newinsert), true);
			}
			else    //  paretn->_color==RED
			{
				if (parent == parent->_parent->_left)   //  cur 和 parent位于 g左边的情况
				{
					RBTreeNode* uncle = parent->_parent->_right;
					if (uncle == nullptr && cur == parent->_left)   //  开始即结束  直接变形
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle == nullptr && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle->_color == RED)    //向上调    //  cur  位于  parent的左边 右边都行
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK && cur == parent->_left)  //  开始旋转
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent);
						RotateR(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return make_pair(iterator(newinsert), true);
					}
				}
				else    //  parent==paretn->_parent->_right
				{
					RBTreeNode* uncle = parent->_parent->_left;
					if (uncle == nullptr && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						Grandp->_color = RED;
						parent->_color = BLACK;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle == nullptr && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						cur->_color = BLACK;
						Grandp->_color = RED;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle->_color == RED)
					{
						parent->_color = BLACK;
						uncle->_color = BLACK;
						if (parent->_parent != _node)
						{
							parent->_parent->_color = RED;
						}
						cur = parent->_parent;
						parent = cur->_parent;
					}
					else if (uncle->_color == BLACK && cur == parent->_left)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateL(parent->_parent);
						parent->_color = BLACK;
						Grandp->_color = RED;
						return make_pair(iterator(newinsert), true);
					}
					else if (uncle->_color == BLACK && cur == parent->_right)
					{
						RBTreeNode* Grandp = parent->_parent;
						RotateR(parent);
						RotateL(Grandp);
						Grandp->_color = RED;
						cur->_color = BLACK;
						return make_pair(iterator(newinsert), true);
					}
				}
			}
		}
	}


	void RotateL(RBTreeNode* root)
	{
		if (root == nullptr)
		{
			return;
		}

		RBTreeNode* rootR = root->_right;
		root->_right = rootR->_left;
		if (rootR->_left)
		{
			rootR->_left->_parent = root;
		}


		rootR->_left = root;
		RBTreeNode* g = root->_parent;
		root->_parent = rootR;


		if (root == _node)
		{
			_node = rootR;
			rootR->_parent = nullptr;
		}
		else
		{
			rootR->_parent = g;
			if (root == g->_left)
			{
				g->_left = rootR;
			}
			else
			{
				g->_right = rootR;
			}
		}
	}

	void RotateR(RBTreeNode* root)
	{
		if (root == nullptr)
		{
			return;
		}

		RBTreeNode* rootL = root->_left;
		root->_left = rootL->_right;
		if (rootL->_right)
		{
			rootL->_right->_parent = root;
		}


		rootL->_right = root;
		RBTreeNode* g = root->_parent;
		root->_parent = rootL;


		if (root == _node)
		{
			_node = rootL;
			rootL->_parent = nullptr;
		}
		else
		{
			rootL->_parent = g;
			if (root == g->_left)
			{
				g->_left = rootL;
			}
			else
			{
				g->_right = rootL;
			}
		}
	}

	RBTreeNode* GetNode()
	{
		return _node;
	}
private:
	RBTreeNode* _node;
};

map.h

#pragma once
#include<iostream>
using namespace std;
#include".h"

template<class K, class V>
class map
{
public:
	struct MakeKeyOfT        //    用仿函数,获取键值
	{
		const K& operator()(const pair<K, V>& kv)
		{
			return kv.first;
		}
	};
	struct MakeKeyOfT2       
	{
		const V& operator()(const pair<K, V>& kv)
		{
			return kv.second;
		}
	};

	typedef typename RBTree<K, pair<K,V>, MakeKeyOfT>::iterator iterator;    // 因为iterator 在RBTree中也是引用的,需要加typename
	pair<iterator,bool> Insert(const K& key,const V& value)
	{
		return _map.Insert(make_pair(key,value));
	}

	iterator begin()
	{
		return _map.begin();
	}

	iterator end()
	{
		return _map.end();
	}



	MakeKeyOfT koft;
	MakeKeyOfT2 koft2;
	void _InOrder(RBTreeNode<pair<K,V>>* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_left);
		cout << koft(root->_kv) << " " << koft2(root->_kv)<< endl;
		_InOrder(root->_right);
	}

	void InOrder()
	{
		_InOrder(_map.GetNode());
	}


	V& operator[](const K& k)
	{
		pair<iterator, bool> ret = _map.Insert(make_pair(k, V()));     //  V() 默认为0或空
		{
			return ret.first->second;
		}
	}




private:
	RBTree<K, pair<K, V>, MakeKeyOfT> _map;       //   由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
};

set.h

#pragma once
#include<iostream>
using namespace std;
#include".h"

template<class K>
class set
{
public:
	struct MakeKeyOfT        //    用仿函数,获取键值,为了与map一致,也写一个仿函数,形成统一接口
	{
		const K& operator()(const K& k)
		{
			return k;
		}
	};
	MakeKeyOfT koft;

	typedef typename RBTree<K, K, MakeKeyOfT>::iterator iterator;
	pair<iterator,bool> Insert(const K& k)
	{
		return _set.Insert(k);
	}

	void _InOrder(RBTreeNode<K>* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->_left);
		cout << koft(root->_kv)<< endl;
		_InOrder(root->_right);
	}


	void InOrder()
	{
		_InOrder(_set.GetNode());
	}


	iterator beign()
	{
		return _set.begin();
	}


	iterator end()
	{
		return _set.end();
	}

private:
	RBTree<K, K, MakeKeyOfT> _set;       //   由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值