【C++】红黑树以及map和set的模拟实现


要求:熟悉红黑树概念,性质,以及插入的原理,并画图实现

1. 红黑树的概念

红黑树是一棵二叉搜索树。它有颜色限制,只能是红色或者黑色。且在根节点到空节点的路径中,最长路径不超过最短路径的两倍,所以红黑树是接近平衡的。
在这里插入图片描述

注意有的地方说NIL是叶子节点,其实NIL节点就是空节点。


2. 红黑树的性质

  1. 每个节点不是红色的就是黑色的。
  2. 根节点是黑色的。
  3. NIL节点都是黑色的。
  4. 如果一个节点是红色的,它的两个孩子节点都是黑色的;如果一个节点是红色的,其父节点一定是黑色的。即任何路径都没有连续的红色节点。
  5. 每条路径上黑色节点的数目是相同。

结论根据红黑树的性质,我们可以得到一个结论:最长路径不超过最短路径的两倍。所以红黑树是接近平衡。
在这里插入图片描述


3. 红黑树的实现

  1. 定义

(1)红黑树采用三叉链的存储结构。
(2)红黑树带有一个头节点,头节点的parent指向根节点,左孩子指向最左节点,右孩子指向最右节点。
在这里插入图片描述
代码

//颜色
enum color
{
	RED,
	BLACK
};
//节点
//T可以是key
template<class T>
struct RBTreeNode
{
	T _data;
	color _col;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	RBTreeNode(const T& data)
		:_data(data)
		, _col(RED)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
	{}
};
//KeyOfT是仿函数,重载了(),返回key。
//为什么返回key,因为节点存放的可能是K,也可能是pair<K,V>,而插入比较是K,所以就返回key。
template<class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	RBTree()
		: _size(0)
	{
		_pHead = new Node(T());
		_pHead->_left = _pHead;
		_pHead->_right = _pHead;
		_pHead->_parent = nullptr;
	}
private:
	Node* _pHead;
	_size_t size;
}

问题
为什么将节点的默认颜色设置为红色?
一个新节点作为要插入的节点,不能是黑色节点。因为会影响其他路径的黑色节点,不能保证每条路径的黑色节点数目相同。而插入红色节点不影响其他路径,只影响当前路径。

  1. 插入

(1)红黑树是二叉搜索树,满足二叉搜索树的性质。所以先将节点插入,再来考虑是否需要对节点进行调整。
(2)如果插入节点的父节点是黑色的,插入新节点就不破坏红黑树的结构。
在这里插入图片描述
(3)如果插入节点的父节点是红色的(其祖父节点一定是黑色的),就得考虑以下两种情况:
a. 父亲节点为红色节点,叔叔节点为红色节点
在这里插入图片描述

b. 父节点为红色节点,叔叔节点为空,或者叔叔节点为黑色节点
在这里插入图片描述

(3)总结:红黑树插入关键看uncle节点。当uncle存在且为红色,变色+向上调整;当uncle不存在或者存在且为黑色时,旋转+变色,旋转后路径就变短,接近平衡。

(4)例子
在这里插入图片描述
(5)代码

template<class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	
	//...
	// 插入值为data的节点
	// 返回值含义:iterator代表新插入节点的迭代器   bool:代表释放插入是够成功
	pair<iterator, bool> Insert(const T& data)
	{
		KeyOfT kot;

		//先插入,再调整颜色
		if (_pHead->_parent == nullptr)
		{
			_pHead->_parent = new Node(data);
			_pHead->_parent->_col = BLACK;
			_pHead->_parent->_parent = _pHead;
			return make_pair(iterator(_pHead->_parent), true);
		}
		Node* parent = nullptr;
		Node* cur = _pHead->_parent;//根结点
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(iterator(cur),false);
			}
		}
		cur = new Node(data);
		cur->_parent = parent;
		cur->_col = RED;//默认设置为红色
		if (kot(parent->_data) < kot(cur->_data))
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}

		//记录新插入节点,方便后面返回
		Node* newnode = cur;

		//若parent为黑节点,则不用调整
		//若parent为红节点,则grandfather一定为黑节点,此时颜色的调整取决于uncle
		//uncle为红节点,直接将p和u变黑,g变红,再将cur = g,继续判断
		//uncle不存在或者为黑节点,旋转+颜色调整
		while (parent!=_pHead && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				//uncle存在且为红色
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;
					cur = grandfather;//如果cur是根节点,根节点是红色,不用担心,出了循环会处理
					parent = cur->_parent;
				}
				//uncle不存在或者存在且为黑色
				else
				{
					//右旋g,将p变黑,g变红
					if (cur == parent->_left)
					{
						//		g
						//	 p
						//c
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					//左旋p,右旋g
					else
					{
						//		g
						//	 p
						//		c
						RotateL(parent);
						RotateR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}
			//parent在grandparent的右边
			else
			{
				Node* uncle = grandfather->_left;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;
					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					//左旋g,将g变红,p变黑
					if (cur == parent->_right)
					{
						//		g
						//			p
						//				c
						RotateL(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					//先右旋p,再左旋g,将g变黑,c变红
					else
					{
						//		g
						//			p
						//		c
						RotateR(parent);
						RotateL(grandfather);
						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}
		}
		_pHead->_parent->_col = BLACK;
		//记得更新最大节点和最小节点
		_pHead->_left = _LeftMost();//返回最左节点(最小节点)
		_pHead->_right = _RightMost();//返回最右边节点(最大节点)
		++_size;
		return make_pair(iterator(newnode),true);
	}
private:
	void RotateL(Node* pParent)
	{
		Node* cur = pParent->_right;
		Node* curleft = cur->_left;

		pParent->_right = curleft;
		if (curleft)
		{
			curleft->_parent = pParent;
		}
		cur->_left = pParent;
		//不要忘记父节点的链接
		Node* pparent = pParent->_parent;
		pParent->_parent = cur;
		//要考虑parent的parent是否存在
		if (pparent != _pHead)
		{
			if (pparent->_left == pParent)
			{
				pparent->_left = cur;
			}
			else
			{
				pparent->_right = cur;
			}
			cur->_parent = pparent;
		}
		else
		{
			_pHead->_parent = cur;
			cur->_parent = _pHead;
		}
	}
	void RotateR(Node* pParent)
	{
		Node* cur = pParent->_left;
		Node* curright = cur->_right;
		pParent->_left = curright;
		if (curright)
		{
			curright->_parent = pParent;
		}
		cur->_right = pParent;

		Node* pparent = pParent->_parent;
		pParent->_parent = cur;
		if (pparent != _pHead)
		{
			if (pparent->_left == pParent)
			{
				pparent->_left = cur;
			}
			else
			{
				pparent->_right = cur;
			}
			cur->_parent = pparent;
		}
		else
		{
			_pHead->_parent = cur;
			cur->_parent = _pHead;
		}
	}
	Node* _LeftMost()
	{
		Node* cur = _pHead->_parent;
		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return cur;
	}
	Node* _RightMost()
	{
		Node* cur = _pHead->_parent;
		while (cur->_right)
		{
			cur = cur->_right;
		}
		return cur;
	}
}
  1. 迭代器
template<class T>
struct RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef RBTreeIterator<T> Self;

	RBTreeIterator(Node* pNode)
		: _pNode(pNode)
	{}

	// 让迭代器具有类似指针的行为
	T& operator*()
	{
		return _pNode->_data;
	}
	T* operator->()
	{
		return &_pNode->_data;
	}

	// 让迭代器可以移动:前置/后置++  
	Self& operator++()
	{
		Increament();
		return *this;
	}
	Self operator++(int)
	{
		RBTreeIterator tmp(_pNode);
		Increament();
		return tmp;
	}
	// 然迭代器可以移动:前置/后置-- 
	Self& operator--()
	{
		DeIncreament();
		return *this;
	}
	Self operator--(int)
	{
		RBTreeIterator tmp(_pNode);
		DeIncreament();
		return tmp;
	}

	// 让迭代器可以比较
	bool operator!=(const Self& s)const
	{
		return _pNode != s._pNode;
	}
	bool operator==(const Self& s)const
	{
		return _pNode == s._pNode;
	}

private:
	//增加
	void Increament()
	{
		//如果_pNode的右子树存在,来到右子树的最左节点
		if (_pNode->_right)
		{
			Node* leftmost = _pNode->_right;
			while (leftmost->_left)
			{
				leftmost = leftmost->_left;
			}
			_pNode = leftmost;
		}
		else
		{
			//如果cur是parent的左孩子,那么parent就是下一个节点。
			//如果cur是parent的右孩子,说明parent已经访问过了,继续往上调整。
			Node* cur = _pNode;
			Node* parent = _pNode->_parent;
			//parent是头节点时,cur是根节点,此时循环停止
			while (parent->_parent != cur && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}
			_pNode = parent;
		}
	}
	//减少
	void DeIncreament()
	{
		//注意如果_pNode是头节点的话,--操作,_pNode要指向最右节点
		if (_pNode->_parent->_parent = _pNode)
		{
			_pNode = _pNode->_right;
		}
		//如果_pNode的左子树存在,来到左子树的最右节点
		else if (_pNode->_left)
		{
			Node* rightmost = _pNode->_left;
			while (rightmost->_right)
			{
				rightmost = rightmost->_right;
			}
			_pNode = rightmost;
		}
		else
		{
			//如果cur是parent的右孩子,那么parent就是下一个要访问的节点
			//如果cur是parent的左孩子,说明parent已经访问过了,继续网上调整。
			Node* cur = _pNode;
			Node* parent = _pNode->_parent;
			while (parent->_parent != cur && cur == parent->_left)
			{
				cur = parent;
				parent = parent->_parent;
			}
			_pNode = parent;
		}
	}
	Node* _pNode;
};

template<class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef RBTreeIterator<T> iterator;
	//...
	// Begin和End迭代器
	iterator Begin()
	{
		return iterator(_pHead->_left);
	}
	iterator End()
	{
		return iterator(_pHead);
	}
	//....
}
  1. 判断平衡
template<class T, class KeyOfT>
class RBTree
{
	//...
	//判断是否是RBTree
	//不能单纯通过最长路径不超过最短路径这一特点来判断是否是RBTree
	//要通过RBTree的性质来判断
	bool IsRBTree()
	{
		return IsRBTree(_pHead->_parent);
	}

	bool IsRBTree(Node* root)
	{
		if (root == nullptr)
		{
			return true;
		}

		//根节点不是红节点
		if (root->_col == RED)
		{
			return false;
		}
		//不能有连续的红节点,每条路径上黑节点数目相同
		int benchmark = 0;//记录一条路径上的黑节点作为基准值,然后比较每条路径的黑节点数目
		Node* cur = root;
		while (cur)
		{
			if (cur->_col == BLACK)
			{
				++benchmark;
			}
			cur = cur->_left;
		}
		return CheckColor(root, 0, benchmark);
	}

	bool CheckColor(Node* root, int blacknum, int benchmark)
	{
		if (root == nullptr)
		{
			//如果黑节点数目不等于基准值,说明黑节点数目不一致,返回false
			if (blacknum != benchmark)
			{
				return false;
			}
			return true;
		}
		if (root->_col == BLACK)
		{
			++blacknum;
		}
		//检查有没有连续的红节点
		else if (root->_col == RED)
		{
			if (root->_parent->_col == RED)
			{
				return false;
			}
		}
		return CheckColor(root->_left, blacknum, benchmark) && CheckColor(root->_right, blacknum, benchmark);
	}
}
  1. 其他操作
template<class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef RBTreeIterator<T> iterator;
	// 红黑树是否为红,是返回true,否则返回false
	bool Empty()const
	{
		return _size == 0;
	}
	// 返回红黑树中有效节点的个数
	size_t Size()const
	{
		return _size;
	}
	// 将红黑树中的有效节点删除,注意:删除的是有效节点,不删除头结点
	void Clear()
	{
		_Destroy(_pHead->_parent);
	}
	// 在红黑树中查找data,存在赶回该节点对应的迭代器,否则返回End()
	iterator Find(const T& data)
	{
		KeyOfT kot;
		Node* cur = _pHead->_parent;
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				cur = cur->_left;
			}
			else
			{
				return iterator(cur);
			}
		}
		return iterator(_pHead);
	}
	//高度
	int Height()
	{
		return Height(_pHead->_parent);
	}

	int Height(Node* root)
	{
		if (root == nullptr)
			return 0;

		int leftHeight = Height(root->_left);
		int rightHeight = Height(root->_right);

		return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
	}
private:
	//...
	void _Destroy(Node*& pRoot)
	{
		if (pRoot == nullptr)
		{
			return;
		}
		_Destroy(pRoot->_left);
		_Destroy(pRoot->_right);
		delete pRoot;
		pRoot = nullptr;
	}
	//...

4. map和set的模拟实现

MyRBTree.h

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

//颜色
enum color
{
	RED,
	BLACK
};
//节点
template<class T>
struct RBTreeNode
{
	T _data;
	color _col;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;

	RBTreeNode(const T& data)
		:_data(data)
		, _col(RED)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
	{}
};

template<class T, class Ref, class Ptr>
struct RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef RBTreeIterator<T, Ref, Ptr> Self;

	typedef RBTreeIterator<T, T&, T*> iterator;
	RBTreeIterator(const iterator& it)
	{
		_pNode = it._pNode;
	}

	RBTreeIterator(Node* pNode)
		: _pNode(pNode)
	{}

	// 让迭代器具有类似指针的行为
	Ref operator*()
	{
		return _pNode->_data;
	}
	Ptr operator->()
	{
		return &_pNode->_data;
	}

	// 让迭代器可以移动:前置/后置++  
	Self& operator++()
	{
		Increament();
		return *this;
	}
	Self operator++(int)
	{
		RBTreeIterator tmp(_pNode);
		Increament();
		return tmp;
	}
	// 然迭代器可以移动:前置/后置-- 
	Self& operator--()
	{
		DeIncreament();
		return *this;
	}
	Self operator--(int)
	{
		RBTreeIterator tmp(_pNode);
		DeIncreament();
		return tmp;
	}

	// 让迭代器可以比较
	bool operator!=(const Self& s)const
	{
		return _pNode != s._pNode;
	}
	bool operator==(const Self& s)const
	{
		return _pNode == s._pNode;
	}

	//增量
	void Increament()
	{
		if (_pNode->_right)
		{
			Node* leftmost = _pNode->_right;
			while (leftmost->_left)
			{
				leftmost = leftmost->_left;
			}
			_pNode = leftmost;
		}
		else
		{
			Node* cur = _pNode;
			Node* parent = _pNode->_parent;
			//parent是头节点时,cur是根节点,此时循环停止
			while (parent->_parent != cur && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}
			_pNode = parent;
		}
	}
	//减少量
	void DeIncreament()
	{
		//注意如果_pNode是头节点的话,--操作,_pNode要指向最右节点
		if (_pNode->_parent->_parent = _pNode)
		{
			_pNode = _pNode->_right;
		}
		else if (_pNode->_left)
		{
			Node* rightmost = _pNode->_left;
			while (rightmost->_right)
			{
				rightmost = rightmost->_right;
			}
			_pNode = rightmost;
		}
		else
		{
			Node* cur = _pNode;
			Node* parent = _pNode->_parent;
			while (parent->_parent != cur && cur == parent->_left)
			{
				cur = parent;
				parent = parent->_parent;
			}
			_pNode = parent;
		}
	}
	Node* _pNode;
};

// K: 作为查找和删除等函数的参数类型,实际就是T中的key
// T: 可能是键值对<key,value>
//    可能是一个key
// 不论节点中存储的是<key, value> || key, 都是按照key来进行比较的
// KeyOfValue: 提取data中的Key
template<class K, class T, class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef RBTreeIterator<T, T&, T*> iterator;
	typedef RBTreeIterator<T,const T&,const T*> const_iterator;

	RBTree()
		: _size(0)
	{
		_pHead = new Node(T());
		_pHead->_left = _pHead;
		_pHead->_right = _pHead;
		_pHead->_parent = nullptr;
	}


	// Begin和End迭代器
	iterator Begin()
	{
		return iterator(_pHead->_left);
	}
	iterator End()
	{
		return iterator(_pHead);
	}
	// const迭代器
	const_iterator Begin()const
	{
		return const_iterator(_pHead->_left);
	}
	const_iterator End()const
	{
		return const_iterator(_pHead);
	}


	// 插入值为data的节点
	// 返回值含义:iterator代表新插入节点   bool:代表释放插入成功
	pair<iterator, bool> Insert(const T& data)
	{
		KeyOfT kot;

		//先插入,再调整颜色
		if (_pHead->_parent == nullptr)
		{
			_pHead->_parent = new Node(data);
			_pHead->_parent->_col = BLACK;
			_pHead->_parent->_parent = _pHead;
			return make_pair(iterator(_pHead->_parent), true);
		}
		Node* parent = nullptr;
		Node* cur = _pHead->_parent;//根结点
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(iterator(cur),false);
			}
		}
		cur = new Node(data);
		cur->_parent = parent;
		cur->_col = RED;//默认设置为红色
		if (kot(parent->_data) < kot(cur->_data))
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}

		//方便后面返回新插入节点的迭代器
		Node* newnode = cur;

		//若parent为黑节点,则不用调整
		//若parent为红节点,则grandfather一定为黑节点,此时颜色的调整取决于uncle
		//uncle为红节点,直接将p和u变黑,g变红,再将cur = g,继续判断
		//uncle不存在或者为黑节点,旋转+颜色调整
		while (parent!=_pHead && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				//uncle存在且为红色
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;
					cur = grandfather;//如果根节点是红色,不用担心,出了循环会处理
					parent = cur->_parent;
				}
				//uncle不存在或者存在且为黑色
				else
				{
					//右旋g,将p变黑,g变红
					if (cur == parent->_left)
					{
						//		g
						//	 p
						//c
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					//左旋p,右旋g
					else
					{
						//		g
						//	 p
						//		c
						RotateL(parent);
						RotateR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}
			//parent在grandparent的右边
			else
			{
				Node* uncle = grandfather->_left;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;
					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					//左旋g,将g变红,p变黑
					if (cur == parent->_right)
					{
						//		g
						//			p
						//				c
						RotateL(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					//先右旋p,再左旋g,将g变黑,c变红
					else
					{
						//		g
						//			p
						//		c
						RotateR(parent);
						RotateL(grandfather);
						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}
		}
		_pHead->_parent->_col = BLACK;
		//记得更新最大节点
		_pHead->_left = _LeftMost();
		_pHead->_right = _RightMost();
		++_size;
		return make_pair(iterator(newnode),true);
	}

	// 红黑树是否为红,是返回true,否则返回false
	bool Empty()const
	{
		return _size == 0;
	}
	// 返回红黑树中有效节点的个数
	size_t Size()const
	{
		return _size;
	}
	// 将红黑树中的有效节点删除,注意:删除的是有效节点,不删除头结点
	void Clear()
	{
		_Destroy(_pHead->_parent);
	}
	// 在红黑树中查找data,存在赶回该节点对应的迭代器,否则返回End()
	iterator Find(const T& data)
	{
		KeyOfT kot;
		Node* cur = _pHead->_parent;
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				cur = cur->_left;
			}
			else
			{
				return iterator(cur);
			}
		}
		return iterator(_pHead);
	}

private:
	Node* _LeftMost()
	{
		Node* cur = _pHead->_parent;
		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return cur;
	}
	Node* _RightMost()
	{
		Node* cur = _pHead->_parent;
		while (cur->_right)
		{
			cur = cur->_right;
		}
		return cur;
	}
	void _Destroy(Node*& pRoot)
	{
		if (pRoot == nullptr)
		{
			return;
		}
		_Destroy(pRoot->_left);
		_Destroy(pRoot->_right);
		delete pRoot;
		pRoot = nullptr;
	}
	void RotateL(Node* pParent)
	{
		Node* cur = pParent->_right;
		Node* curleft = cur->_left;

		pParent->_right = curleft;
		if (curleft)
		{
			curleft->_parent = pParent;
		}
		cur->_left = pParent;
		//不要忘记父节点的链接
		Node* pparent = pParent->_parent;
		pParent->_parent = cur;
		//要考虑parent的parent是否存在
		if (pparent != _pHead)
		{
			if (pparent->_left == pParent)
			{
				pparent->_left = cur;
			}
			else
			{
				pparent->_right = cur;
			}
			cur->_parent = pparent;
		}
		else
		{
			_pHead->_parent = cur;
			cur->_parent = _pHead;
		}
	}
	void RotateR(Node* pParent)
	{
		Node* cur = pParent->_left;
		Node* curright = cur->_right;
		pParent->_left = curright;
		if (curright)
		{
			curright->_parent = pParent;
		}
		cur->_right = pParent;

		Node* pparent = pParent->_parent;
		pParent->_parent = cur;
		if (pparent != _pHead)
		{
			if (pparent->_left == pParent)
			{
				pparent->_left = cur;
			}
			else
			{
				pparent->_right = cur;
			}
			cur->_parent = pparent;
		}
		else
		{
			_pHead->_parent = cur;
			cur->_parent = _pHead;
		}
	}
private:
	Node* _pHead;
	size_t _size;
};

MySet.h

#pragma once
#include"MyRBTree2.0.h"
namespace zn
{
	template<class K>
	class set
	{
		//直接返回key
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		//编译器不知道iterator是类型还是静态成员记得+typename,告诉编译器这是类型
		//set存储类型是K,K不能修改,所以set的普通迭代器实际上是const迭代器
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator iterator;
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;
		
		//调用const迭代器,得用const修饰的this去调用
		iterator begin()const
		{
			return _t.Begin();
		}
		iterator end()const
		{
			return _t.End();
		}
		//这里的iterator是const_iterator
		pair<iterator, bool> insert(const K& key)
		{
			pair<typename RBTree<K,K,SetKeyOfT>::iterator,bool> ret =  _t.Insert(key);//RBTree的Insert返回的pair中的iterator是普通iterator
			//需要将普通iterator转换成const_iterator
			//这里是用普通迭代器去构造const迭代器,所以在迭代器中写一个构造
			return pair<iterator, bool>(ret.first, ret.second);
		}

	private:
		//因为map和set用的是同一个类模板,所以set还是要传三个模板参数
		//第一个K是map的find等函数用来接收参数的参数类型,map不能从pair中提取K,所以只能传K,
		//这也导致set也得传第一个K
		//第二个K是set的存储类型
		RBTree<K, K, SetKeyOfT> _t;
	};
}
MyMap.h

#pragma once
#include"MyRBTree2.0.h"
namespace zn
{
	template<class K, class V>
	class map
	{
		//用来返回pair中的key
		struct MapKeyOfT
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		//编译器不知道iterator是类型还是静态成员记得+typename,告诉编译器这是类型
		//pair中的K不能修改,所以+const
		typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::iterator iterator;
		typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;

		iterator begin()
		{
			return _t.Begin();
		}

		iterator end()
		{
			return _t.End();
		}

		const_iterator begin()const
		{
			return _t.Begin();
		}

		const_iterator end()const
		{
			return _t.End();
		}

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

		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert(make_pair(key, V()));
			return ret.first->second;
		}

	private:
		RBTree<K, pair<const K, V>, MapKeyOfT> _t;
	};
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值