红黑树来实现map&set

在这里插入图片描述

目录:

一.修改红黑树

这篇博客是对于红黑树来实现map和set,所以代码不详细的注释,了解红黑树看红黑树的具体实现

底层实现原理:

如果我们要利用红黑树来实现map和set的时候,我们就会发现map是对应的<K,V>键值对,而set是<K,K> 所以我们在这里进行实现的时候,就要引入第三个模板类,首先对于要输出的值进行一个封装,再通过其第三个模板类进行数据的引入,直接去引入对饮的个kv键值对或者直接引入对应得val即可.

enum COLOR{};
template <class V>
struct RBNode{};
//KeyOfValue: 通过v获取对应的K
template<class K, class V, class KeyOfValue>
class RBTree{
public:
	typedef RBNode<V> Node;	
	
	RBTree()
		:_header(new Node)
	{
	
		_header->_left = _header->_right = _header;
	}

	bool insert(const V& val){


		if (_header->_parent == nullptr){

		
			Node* root = new Node(val);

			_header->_parent = root;
			root->_parent = _header;
			_header->_left = _header->_right = root;

	
			root->_color = BLACK;
			return true;
		}

		Node* cur = _header->_parent;
		Node* parent = nullptr;

		KeyOfValue kov;
		while (cur){

			parent = cur;

//if (cur->_val.first ==val.first)
			if (kov(cur->_val) == kov(val))	//在这里判断的时候,引入第三个模板来实现取出对应的数据
			{
				return false;
			}
//else if (cur->_val.first > val.first)
			else if (kov(cur->_val)>kov(val))
			{
				cur = cur->_left;
			}
			else{
				cur = cur->_right;
			}
		}
	
		cur = new Node(val);
		if (kov(parent->_val) > kov(cur->_val))
			parent->_left = cur;
		else
			parent->_right = cur;
		cur->_parent = parent;
		
		while (cur != _header->_parent && cur->_parent->_color == RED){

			parent = cur->_parent;
			Node* gfather = parent->_parent;

			if (gfather->_left == parent){

				Node* uncle = gfather->_right;
		
				if (uncle&&uncle->_color == RED){

					parent->_color = uncle->_color = BLACK;
					gfather->_color = RED;
	
					cur = gfather;
				}
				else{

					if (cur == parent->_right){

						RotateL(parent);
						swap(cur, parent);
					}
		
					RotateR(gfather);
					parent->_color = BLACK;
					gfather->_color = RED;
					break;
				}
			}
			else{
//gfather->right=parent
				Node* uncle = gfather->_left;
				if (uncle&&uncle->_color == RED){

					parent->_color = uncle->_color = BLACK;
					gfather->_color = RED;
					cur = gfather;
				}
				else{

					if (cur == parent->_left){

						RotateR(parent);
						swap(cur, parent);
					}
					RotateL(gfather);

					parent->_color = BLACK;
					gfather->_color = RED;
					break;
				}
			}
		}
		_header->_parent->_color = BLACK;

		_header->_left = leftMost();
		_header->_right = rightMost();
	}
	//下面这些没有写的接口和原来的代码一致,没有改变,想看去看红黑树的代码
	void RotateL(Node* parent);
	void RotateR(Node* parent);
	Node* leftMost();
	Node* rightMost();
	void inorder();
	void _inorder(Node* root);
	bool isBalance();
	bool _isBalance(Node* root, int& bCount, int curBCount);

private:
	Node* _header;
};

二.红黑树实现map

template<class K, class T>
class Map{
	//通过这里的传值来体现map和set的不同
	struct MapKeyOfValue{
		const K& operator()(const pair<K, T>& val){		//构建出对应的值

			return val.first;
		}
	};

public:

	bool insert(const pair<K, T>& kv){	//插入接口直接调用红黑树的接口

		return _rbt.insert(kv);
	}

	T& operator[](const K& key){

		bool ret = _rbt.insert(make_pair(key, T()));	//调用红黑树的接口将对应的两个值插入
	}

private:
	typedef RBTree<K, pair<K, T>, MapKeyOfValue> rbt;	//引入第三个模板类
	rbt _rbt;
};

三.红黑树实现set

template<class K>
class Set{

	struct SetKeyOfValue{
		const K& operator()(const K& val){	//构造函数,只传入对应的key

			return val;
		}
	};
public:
	bool insert(const K& val){		//只传入对应的key

		return _rbt.insert(val);	
	}
private:
	typedef RBTree<K, K, SetKeyOfValue> rbt;	//引入第三个对应的模板
	rbt _rbt;
};

注意:

我们在这里主要理解的是,在我们引入第三个模板的时候,就可以不需要在红黑树上进行改变就可以同时的实现map和set,我们可以直接在对应的构造函数的私有类里面去定义取出对应的需要红黑树的哪一部分的数据.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值