【C++STL(十二)】一棵红黑树简单模拟实现map和set

目录

前言

一、改造红黑树(重点)

改造结点类

改造主体

参数改造

仿函数的增加

正向迭代器实现

反向迭代器实现

改造后的红黑树完整

二、map模拟实现

三、set模拟实现


前言

在前面简单实现的红黑树,实际大家发现是写死的,也就是里面的数据类型是pair,它确实可以封装成map,但是set呢?而实际上set和map底层实现逻辑大差不差,没有必要写重复的两份代码,所以这时就可以采用模板和泛型编程就能解决这样的问题。那么我们就需要来改造改造已有的红黑树了。这里为了方便,先给出原来实现的KV模型的红黑树。

#include <iostream>
using namespace std;
 
//枚举颜色
enum Color
{
	RED,
	BLACK
};
template<class K, class V>
struct RBTreeNode
{
	RBTreeNode<K, V>* _left;
	RBTreeNode<K, V>* _right;
	RBTreeNode<K, V>* _parent;
 
	pair<K, V> _kv;
	Color _co;
	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _co(RED)
	{}
};
 
template<class K, class V>
class RBTree
{
	typedef RBTreeNode<K, V> Node;
public:
	bool Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			_root->_co = BLACK;//根结点一定为黑
			return true;
		}
		//找位置插入
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (kv.first > cur->_kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kv.first < cur->_kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(kv);
		cur->_co = RED;//新增结点一定为红色
		if (kv.first > parent->_kv.first)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;
 
		//插入后,开始调色
		//分情况调色
		while (parent && parent->_co == RED)//调到黑色或者空就停止
		{
			Node* g = parent->_parent;
			if (parent == g->_left)//父亲在左,叔叔在右
			{
				Node* u = g->_right;
				//情况一:叔叔存在且为红,叔叔和父亲变红,爷爷g变黑
				if (u && u->_co == RED)
				{
					parent->_co = u->_co = BLACK;
					g->_co = RED;
 
					//向上调整
					cur = g;
					parent = cur->_parent;
				}
				else//叔叔不存在或者存在且为黑
				{
					//    g
					//  p   u
					// c
					//右单旋,p变黑,g变红
					if (cur == parent->_left)
					{
						RotaRTree(g);
						parent->_co = BLACK;
						g->_co = RED;
					}
					//    g
					//  p   u
					//    c
					//左右双旋,先左再右。cur就变成了p的父亲
					else
					{
						RotaLTree(parent);//左单旋
						RotaRTree(g);//右单旋
						cur->_co = BLACK;
						g->_co = RED;
					}
					//不需要再调整,直接结束
					break;
				}
			}
			else//父亲在右,叔叔在左
			{
				Node* u = g->_left;
				if (u && u->_co == RED)//u存在且为红
				{
					parent->_co = u->_co = BLACK;
					g->_co = RED;
 
					cur = g;
					parent = cur->_parent;
				}
				else//叔叔不存在或者为黑
				{
					//    g
					//  u   p
					//        c
					//左单旋,p变黑,g变红
					if (cur == parent->_right)
					{
						parent->_co = BLACK;
						g->_co = RED;
						RotaLTree(g);
					}
					//    g
					//  u   p
					//    c
					//右左双旋,先右旋,在左旋
					else
					{
						RotaRTree(parent);//右
						RotaLTree(g);//左
						cur->_co = BLACK;
						g->_co = RED;
					}
					break;
				}
			}
		}
		_root->_co = BLACK;//始终保持根是黑色
		return true;
	}
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
 
	bool IsBalance()
	{
		//根为红就错误
		if (_root->_co == RED)
		{
			cout << "不符合根结点为黑这一规则" << endl;
			return false;
		}
		//先以一条路径为标志位,每条路径上的黑色结点的数和该标志位相比,不一样就不满足规则四
		int refnum = 0;//基准位
		Node* cur = _root;
		while (cur)
		{
			if (cur->_co == BLACK)
				refnum++;
			cur = cur->_left;
		}
		return _IsBalance(_root, 0, refnum);
	}
private:
	Node* _root = nullptr;
	bool _IsBalance(Node* root, int curblacknum, const int refnum)
	{
		if (root == nullptr)
		{
			if (curblacknum != refnum)
			{
				cout << "存在黑色结点不同的路径" << endl;
				return false;
			}
			return true;
		}
		if (root->_co == RED && root->_parent->_co == RED)
		{
			cout << "存在连续两个红色结点" << endl;
			return false;
		}
		if (root->_co == BLACK)
		{
			++curblacknum;
		}
 
		return _IsBalance(root->_left, curblacknum, refnum) && _IsBalance(root->_right, curblacknum, refnum);
	}
	//右旋
	void RotaRTree(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		Node* pparent = parent->_parent;
 
		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;
		subL->_right = parent;
		parent->_parent = subL;
 
		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (parent == pparent->_left)
				pparent->_left = subL;
			else
				pparent->_right = subL;
			subL->_parent = pparent;
		}
	}
	//左旋
	void RotaLTree(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		Node* pparent = parent->_parent;
 
		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;
		subR->_left = parent;
		parent->_parent = subR;
 
		if (parent == _root)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (parent == pparent->_left)
				pparent->_left = subR;
			else
				pparent->_right = subR;
			subR->_parent = pparent;
		}
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->_left);
		cout << root->_kv.first << " ";
		_InOrder(root->_right);
	}
 
};
 

一、改造红黑树(重点)

改造结点类

对于map容器,每一个元素是pair键值对,KV模型;对于set容器,每一个元素就是一个值value,但底层是<value,value>,K模型,所以为了能够很好的兼容两者,这里的结点直接采用模板参数T来表示,T会根据传入的类型进行实例化,传入Key就是Key,传入pair就是pair。实现如下

//T可能是key,也可能是pair<K,V>
template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	
	T _data;
	Color _co;

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

改造主体

参数改造

这里的红黑树模板参数有三个:

template<class K,class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
private:
	Node* _root = nullptr;
};

前两个参数好理解,原来KV,改成KT,这个T是为了好区分。。可能有人会有疑问能不能把红黑树的第一个模板参数去掉?不能的,因为像find这样的接口需要用Key。第三个模板参数主要是为了比较大小。

仿函数的增加

第三个参数KeyOfT实际上用的仿函数,为何?因为所有比较大小的方式需要改变,因为用的同一棵红黑树,那就要兼容。原来插入是pair,但比较大小比的是Key,对于pair来说,取Key就是取first,可是set中并没有first,那怎么取?这就是这个仿函数的作用,根据上层map、set传入的仿函数,取出各自的键值Key比较。如下:

  • set中的仿函数
template<class K>
class set
{
	struct SetKey
	{
		const K& operator()(const K& key)
		{
			return key;
		}
	};

    //……
private:
	RBTree<K, K, SetKey> _s;
};
  • map的仿函数 
template<class K,class V>
class map
{
	//内部类
	struct MapKey
	{
		const K& operator()(const pair<K, V>& kv)
		{
			return kv.first;
		}
	};
    //……
private:
	RBTree<K, pair<K, V>, MapKey> _m;
};

 红黑树的插入

pair<Iterator,bool> Insert(const T& date)
{
	if (_root == nullptr)
	{
		_root = new Node(date);
		_root->_co = BLACK;
		return make_pair(Iterator(_root),true);
	}
	KeyOfT kot;//kot对象
	Node* cur = _root;
	Node* parent = nullptr;
	while (cur)
	{
		//k
		//pair<K,V>
		//kot对象,用来取T类型的data里面的Key
		if (kot(date) > kot(cur->_data))
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (kot(data) < kot(cur->_data))
		{
			parent = cur;
			cur = cur->_left;
		}
		else
		{
			return make_pair(Iterator(cur), false);
		}
	}
	cur = new Node(data);
    Node* newnode=cur;
	cur->_co = RED;//新增结点一定为红色
	if (kot(date) > kot(parent->_data))
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	cur->_parent = parent;

	//插入后,开始调色
	//分情况调色

    //………………………………

所有的比较逻辑都要改变哦!!

正向迭代器实现

这里的迭代器就是和在list模拟实现时的类似,底层就是结点的指针,但因为是树,++/--等操作都不能遍历到下一个结点,所以得封装成自定义类型。

//正向迭代器结构
template<class T, class Ref,class Ptr>
struct __RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __RBTreeIterator<T, T&, T*> Self;

	Node* _node;
	__RBTreeIterator(Node* node)
		:_node(node)
	{}
};

迭代器实现的难点在于:如何进行++/--操作? 

++操作:

实际上离不开中序遍历的规则,左->根->右,也就是主要看右子树的情况,因为遍历完右子树说明这一轮的遍历已经完成了,接下就是找下一个结点。。即左子树。。情况如下:

  • 右子树不为空,下一个结点就是右子树的最左结点
  • 右子树为空,倒着找一个满足以当前结点作为左子树的祖先结点,它就是下一个遍历结点
	Self& operator++()
	{
		//右子树存在,下一个遍历的是右子树最左侧的结点
		if (_node->_right)
		{
			Node* leftMin = _node->_right;
			while (leftMin && leftMin->_left)
			{
				leftMin = leftMin->_left;
			}
			_node = leftMin;
		}
		//右子树不存在,倒着回去找到以当前结点作为左孩子的那个结点
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}

		return *this;
	}

--操作 :

实际上和++操作相反,右->根->左,即主要看左子树的情况。

  • 左子树不为空,下一个结点就是左子树的最右结点。
  • 左子树为空,说明当前结点所在子树已经遍历完成,倒着找满足以当前结点为右子树的祖先结点,即为下一个访问结点。
	Self& operator--()
	{
		//左子树存在,下一个遍历的是左子树最右侧的结点
		if (_node->_left)
		{
			Node* rightMin = _node->_left;
			while (rightMin && rightMin->_right)
			{
				rightMin = rightMin->_right;
			}
			_node = rightMin;
		}
		//左子树不存在,倒着回去找到以当前结点作为右孩子的那个结点,即cur!=parent->left
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_left)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}
		return *this;
	}

反向迭代器实现

实现起来也很容易,实际就是对正向迭代器的封装,是一种适配器模式。这里直接给代码

//反向迭代器
template<class Iterator,class Ref,class Ptr>
struct _ReverIterator
{
	typedef _ReverIterator<Iterator,Ref,Ptr> Self;

	Iterator _it;
	_ReverIterator(Iterator it)
		:_it(it)
	{}

	Ref operator*()
	{
		return *_it;
	}
	Ptr operator->()
	{
		return _it.operator->();
	}

	bool operator!=(const Self& s)
	{
		return _it!=s._it;
	}

	bool operator==(const Self& s)
	{
		return _it==s._it;
	}
	//前置++
	Self& operator++()
	{
		--_it;
		return *this;
	}
	//前置--
	Self& operator--()
	{
		++_it;
		return *this;
	}
};

这里没有实现const迭代器,因为逻辑和非const一样一样的 ,只需在类型前面加上const,对于函数名后加上const即可。

typedef __RBTreeIterator<const T, const T&, const T*> ConstIterator;

ConstIterator Begin()const
{
	Node* leftMin = _root;
	while (leftMin && leftMin->_left)
	{
		leftMin = leftMin->_left;
	}
	return ConstIterator(leftMin);
}

ConstIterator End()const
{
	return ConstIterator(nullptr);
}

改造后的红黑树完整

#pragma once
#include <iostream>
using namespace std;
enum Color
{
	RED,
	BLACK
};

//T可能是key,也可能是pair<K,V>
template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	
	T _data;
	Color _co;

	RBTreeNode(const T& data)
		:_left(nullptr)
		,_right(nullptr)
		,_parent(nullptr)
		,_data(data)
		,_co(RED)
	{}
};
//反向迭代器
template<class Iterator,class Ref,class Ptr>
struct _ReverIterator
{
	typedef _ReverIterator<Iterator,Ref,Ptr> Self;

	Iterator _it;
	_ReverIterator(Iterator it)
		:_it(it)
	{}

	Ref operator*()
	{
		return *_it;
	}
	Ptr operator->()
	{
		return _it.operator->();
	}

	bool operator!=(const Self& s)
	{
		return _it!=s._it;
	}

	bool operator==(const Self& s)
	{
		return _it==s._it;
	}
	//前置++
	Self& operator++()
	{
		--_it;
		return *this;
	}
	//前置--
	Self& operator--()
	{
		++_it;
		return *this;
	}
};

//正向迭代器
template<class T, class Ref,class Ptr>
struct __RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __RBTreeIterator<T, T&, T*> Self;

	Node* _node;
	__RBTreeIterator(Node* node)
		:_node(node)
	{}
	Ref operator*()
	{
		return _node->_data;
	}
	Ptr operator->()
	{
		return &_node->_data;
	}

	bool operator!=(const Self& s)
	{
		return _node != s._node;
	}

	bool operator==(const Self& s)
	{
		return _node == s._node;
	}
	//前置++
	Self& operator++()
	{
		//右子树存在,下一个遍历的是最左侧的结点
		if (_node->_right)
		{
			Node* leftMin = _node->_right;
			while (leftMin && leftMin->_left)
			{
				leftMin = leftMin->_left;
			}
			_node = leftMin;
		}
		//右子树不存在,倒着回去找到以当前结点作为左孩子的那个结点
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}

		return *this;
	}
	//前置--
	Self& operator--()
	{
		//左子树存在,下一个遍历的是左子树最右侧的结点
		if (_node->_left)
		{
			Node* rightMin = _node->_left;
			while (rightMin && rightMin->_right)
			{
				rightMin = rightMin->_right;
			}
			_node = rightMin;
		}
		//左子树不存在,倒着回去找到以当前结点作为右孩子的那个结点,即cur!=parent->left
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_left)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}
		return *this;
	}
};

template<class K,class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef __RBTreeIterator<T, T&, T*> Iterator;
	typedef _ReverIterator<Iterator,T&,T*> ReverIterator;

	RBTree() = default;//强制生成默认构造

	//拷贝构造,前序遍历
	RBTree(const RBTree<K, T, KeyOfT>& r)
	{
		_root = Copy(r._root);
	}

	Node* Copy(Node* root)
	{
		if (root == nullptr)
			return nullptr;

		Node* newroot = new Node(root->_data);
		newroot->_co = root->_co;

		newroot->_left = Copy(root->_left);
		if (newroot->left)
			newroot->_left->_parent = newroot;

		newroot->_right = Copy(root->_right);
		if (newroot->_right)
			newroot->_right->_parent = newroot;

		return newroot;
	}
	//t2=t1
	//现代写法
	RBTree<K, T,KeyOfT>& operator=(RBTree<K, T, KeyOfT> r)
	{
		swap(_root, r._root);
		return *this;
	}

	//析构函数
	~RBTree()
	{
		Destroy(_root);
		_root = nullptr;
	}
	void Destroy(Node* root)
	{
		if (root == nullptr)
			return;
		Destroy(root->_left);
		Destroy(root->_right);
		delete root;
	}
	Iterator Begin()
	{
		Node* leftMin = _root;
		while (leftMin && leftMin->_left)
		{
			leftMin = leftMin->_left;
		}
		return Iterator(leftMin);
	}
	Iterator End()
	{
		return Iterator(nullptr);
	}
	ReverIterator RBegin()
	{
		Node* rightMin = _root;
		while (rightMin && rightMin->_right)
		{
			rightMin = rightMin->_right;
		}
		return ReverIterator(Iterator(rightMin));
	}
	ReverIterator REnd()
	{
		return ReverIterator(nullptr);
	}
	pair<Iterator,bool> Insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_co = BLACK;//根结点一定为黑
			return make_pair(Iterator(_root),true);
		}
		KeyOfT kot;//对象
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			//k
			//pair<K,V>
			//kot对象,用来取T类型的data里面的Key
			if (kot(data) > kot(cur->_data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(data) < kot(cur->_data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(Iterator(cur), false);
			}
		}
		cur = new Node(data);
		Node* newNode = cur;
		cur->_co = RED;//新增结点一定为红色
		if (kot(data) > kot(parent->_data))
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;

		//插入后,开始调色
		//分情况调色
		while (parent && parent->_co == RED)//调到黑色或者空就停止
		{
			Node* g = parent->_parent;
			if (parent == g->_left)//父亲在左,叔叔在右
			{
				Node* u = g->_right;
				//情况一:叔叔存在且为红,叔叔和父亲变红,爷爷g变黑
				if (u && u->_co == RED)
				{
					parent->_co = u->_co = BLACK;
					g->_co = RED;

					//向上调整
					cur = g;
					parent = cur->_parent;
				}
				else//叔叔不存在或者存在且为黑
				{
					//    g
					//  p   u
					// c
					//右单旋,p变黑,g变红
					if (cur == parent->_left)
					{
						RotaRTree(g);
						parent->_co = BLACK;
						g->_co = RED;
					}
					//    g
					//  p   u
					//    c
					//左右双旋,先左再右。cur就变成了p的父亲
					else
					{
						RotaLTree(parent);//左单旋
						RotaRTree(g);//右单旋
						cur->_co = BLACK;
						g->_co = RED;
					}
					//不需要再调整,直接结束
					break;
				}
			}
			else//父亲在右,叔叔在左
			{
				Node* u = g->_left;
				if (u && u->_co == RED)//u存在且为红
				{
					parent->_co = u->_co = BLACK;
					g->_co = RED;

					cur = g;
					parent = cur->_parent;
				}
				else//叔叔不存在或者为黑
				{
					//    g
					//  u   p
					//        c
					//左单旋,p变黑,g变红
					if (cur == parent->_right)
					{
						parent->_co = BLACK;
						g->_co = RED;
						RotaLTree(g);
					}
					//    g
					//  u   p
					//    c
					//右左双旋,先右旋,在左旋
					else
					{
						RotaRTree(parent);//右
						RotaLTree(g);//左
						cur->_co = BLACK;
						g->_co = RED;
					}
					break;
				}
			}
		}
		_root->_co = BLACK;//始终保持根是黑色
		return make_pair(Iterator(newNode), true);
	}
	Iterator Find(const K& key)
	{
		Node* cur = _root;
		KeyOfT kot;
		while (cur)
		{
			if ((key) < kot(cur->_data))
				cur = cur->_left;
			else if (key > kot(cur->_data))
				cur = cur->_right;
			else
				return Iterator(cur);

		}
		return nullptr;
	}
private:
	Node* _root = nullptr;
	//右旋
	void RotaRTree(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		Node* pparent = parent->_parent;

		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;
		subL->_right = parent;
		parent->_parent = subL;

		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (parent == pparent->_left)
				pparent->_left = subL;
			else
				pparent->_right = subL;
			subL->_parent = pparent;
		}
	}
	//左旋
	void RotaLTree(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		Node* pparent = parent->_parent;

		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;
		subR->_left = parent;
		parent->_parent = subR;

		if (parent == _root)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (parent == pparent->_left)
				pparent->_left = subR;
			else
				pparent->_right = subR;
			subR->_parent = pparent;
		}
	}
};

二、map模拟实现

说过底层就是一棵红黑树,所以成员变量就是使用改造后的红黑树进行封装而已咯,没啥的。基本都是调用红黑树的接口。从侧面体现了封装的特性与其强大之处

namespace Ma//模拟实现要在自己的命名空间
{
	template<class K,class V>
	class map
	{
		//内部类
		struct MapKey
		{
			const K& operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
		typedef typename RBTree<K, pair<const K, V>, MapKey>::Iterator iterator;
		typedef typename RBTree<K, pair<const K, V>, MapKey>::ReverIterator rever_iterator;
	public:
		iterator begin()
		{
			return _m.Begin();
		}
		iterator end()
		{
			return _m.End();
		}
		rever_iterator rbegin()
		{
			return _m.RBegin();
		}
		rever_iterator rend()
		{
			return _m.REnd();
		}
		pair<iterator, bool> insert(const pair<K, V>& kv)
		{
			return _m.Insert(kv);
		}
		iterator find(const K& key)
		{
			return _m.Find();
		}

		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = _m.Insert(make_pair(key, V()));
			iterator it = ret.first;
			return it->second;
		}
	private:
		RBTree<K, pair<const K, V>, MapKey> _m;
	};

三、set模拟实现

同样也是红黑树的封装。。。

namespace Se
{
	template<class K>
	class set
	{
		struct SetKey
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		typedef typename RBTree<K, const K, SetKey>::Iterator iterator;
		typedef typename RBTree<K, const K, SetKey>::ReverIterator rever_iterator;

	public:
		iterator begin()
		{
			return _s.Begin();
		}
		iterator end()
		{
			return _s.End();
		}
		rever_iterator rbegin()
		{
			return _s.RBegin();
		}
		rever_iterator rend()
		{
			return _s.REnd();
		}
		pair<iterator, bool> insert(const K& value)
		{
			return _s.Insert(value);
		}
		iterator find(const K& key)
		{
			return _s.Find();
		}
	private:
		RBTree<K, const K, SetKey> _s;
	};

这里说明一下这段代码:

typedef typename RBTree<K, const K, SetKey>::Iterator iterator;
typedef typename RBTree<K, const K, SetKey>::ReverIterator rever_iterator;

typename实际上在模板时有讲过它可以声明模板参数 也就是可以和class替换。但在此处便是它的第二个用处声明嵌套从属名称,如

//嵌套从属名称
RBTree<K, const K, SetKey>::Iterator

 对于这样的情况必须加上typename关键字修饰,否则会报错!!因为使用了模板参数K。在K被编译器具现化之前,是不知道它是什么类型的,也就是无法得知RBTree<K, const K, SetKey>里面的Iterator究竟是什么东西,是类型?函数?其他?编译器是不知道的,加上typename可以告诉编译器它是一个类型!

以上只是简单模拟实现,不是说和库里面完全一样,要是小编能完全和库一样,我直接起飞!重点在体会封装,模板的强大之处。。


今天的分享就到这,如果你有收获,欢迎三连!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值