~set.h
SetKeyofpair
仿函数是为了红黑树比较时能够区分map和set,传MapKeyofpair时,用仿函数去比较就能够区分你到底是传Key过来、还是传pair过来

template<class K>
 class set
{
  struct SetKeyofT
 {
   const K& operator()(const K& key)
   {
    return key;
   }
 };
public:
  bool insert(const K& key)
  {
    return _t.Insert(key);//底层是红黑树,调用红黑树的insert就行了
  }
private:
RBTree<K, K, SetKeyofpair> _t;
 };

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">

~RBtree.h

enum Colour
{
RED,
BLACK
};
template<class T>
struct RBTreeNode
{
T _data;
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
Colour _col;
RBTreeNode(const T& data)
: _data(data)
, _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
{}
};

// 实现步骤:
// 1、实现红⿊树
// 2、封装map和set框架,解决Keyofpair
// 3、iterator
// 4、const_iterator
// 5、key不⽀持修改的问题
// 6、operator[]
template<class K, class T, class KeyOfT>
class RBtree
{
private:
typedef RBTreeNode<T> Node;
Node* _root = nullptr;
public:
bool Insert(const T& data)
{
 if (_root == nullptr)
 {
 _root = new Node(data);
 _root->_col = BLACK;
 return true;
 }
 KeyOfT kot;
 Node* parent = nullptr;
 Node* cur = _root;
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 false;
  }
 }
cur = new Node(data);
Node* newnode = cur;
// 新增结点。颜⾊给红⾊
cur->_col = RED;
 if (kot(parent->_data) < kot(data))
 {
  parent->_right = cur;
 }
 else
 {
  parent->_left = cur;
 }
 cur->_parent = parent;
//...
return true;
 }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.2 ⽀持iterator的实现

红黑树的迭代器可不是++就能得到下一个结点的。
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

terator实现的⼤框架跟list的iterator思路是⼀致的,⽤⼀个类型封装结点的指针再通过重载运算符实现,迭代器像指针⼀样访问的⾏为。


这⾥的难点是operator++和operator–的实现。之前使⽤部分,我们分析了,map和set的迭代器⾛的是中序遍历,左⼦树->根结点->右⼦树,那么begin()会返回中序第⼀个结点的iterator也就是10所在结点的迭代器。

2.2.1红黑树迭代器结构

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

	Node* _node;
	Node* _root;


	RBtreeIterator(Node* node, Node* root)
		:_node(node)
		, _root(root)
	{}
	Ref operator*()
	{
		return _node->_data;
	}

	Ptr operator->()
	{
		return &_node->_data;
	}

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

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

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.2.2 迭代器++

迭代器++的核⼼逻辑就是不看全局,只看局部,只考虑当前中序局部要访问的下⼀个结点
【说明】:中序走法
------------左结点->根结点->右结点

情况一(右子树不为空)++:如果指向的结点的右⼦树不为空,代表当前结点已经访问完了,要访问下⼀个结点是右⼦树的中序第⼀个,⼀棵树中序第⼀个是最左结点,所以直接找右⼦树的最左结点即可。


情况二(右子树为空)++:如果指向的结点的右⼦树空,代表当前结点已经访问完了且当前结点所在的⼦树也访问完了,要访问的下⼀个结点在当前结点的祖先⾥⾯,所以要沿着当前结点到根的祖先路径向上找。

分析:
在这里插入图片描述
右子树为空又可以分成两种情况
情况一:结点是父亲的左
如果当前结点是⽗亲的左,根据中序左⼦树->根结点->右⼦树,那么下⼀个访问的结点就是当前结点的⽗亲;如下图:如果it指向25,25右为空,25是30的左,所以下⼀个访问的结点就是30。
情况二:结点是父亲的右
• 如果当前结点是⽗亲的右,根据中序左⼦树->根结点->右⼦树,当前当前结点所在的⼦树访问完了,当前结点所在⽗亲的⼦树也访问完了,那么下⼀个访问的需要继续往根的祖先中去找,直到找到孩⼦是⽗亲左的那个祖先就是中序要问题的下⼀个结点。如下图:如果it指向15,15右为空,15是10的右,15所在⼦树话访问完了,10所在⼦树也访问完了,继续往上找,10是18的左,那么下⼀个访问的结点就是18。


迭代器end()如何实现呢?
end()如何表⽰呢?如下图:当it指向50时,++it时,50是40的右,40是30的右,30是18的右,18到根没有⽗亲,没有找到孩⼦是⽗亲左的那个祖先,这是⽗亲为空了,那我们就把it中的结点指针置为nullptr,我们⽤nullptr去充当end。这里雨源码不同,我们是用nullptr来实现end(),而源码使用哨兵位头结点实现end()

stl源码实现迭代器end()
在这里插入图片描述
end()不为nullptr,为header(头结点)
在这里插入图片描述

iterator++代码实现

Self operator++() 
{
	if (_node->_right)
	{
		// 右不为空,中序下一个访问的节点是右子树的最左(最小)节点
		Node* min = _node->_right;
		while (min->_left)
		{
			min = min->_left;
		}

		_node = min; 
	}
	else
	{
		// 右为空,祖先里面孩子是父亲左的那个祖先
		Node* cur = _node;
		Node* parent = cur->_parent;
		while (parent && cur == parent->_right)
		{
			cur = parent;
			parent = cur->_parent;
		}

		_node = parent;
	}

	return *this;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.2.4 iterator–

迭代器–的实现跟++的思路完全类似,逻辑正好反过来即可,因为他访问顺序是右⼦树->根结点->左⼦树,具体参考下⾯代码实现。

特殊处理:
–end()的之后,是走到最后一个结点(最右结点)。

	Self operator--()
	{
		if (_node == nullptr)  // --end()
		{
			// --end(),特殊处理,走到中序最后一个结点,整棵树的最右结点
			Node* rightMost = _root;
			while (rightMost && rightMost->_right)
			{
				rightMost = rightMost->_right;
			}
			_node = rightMost;
		}
		else if (_node->_left)
		{
			// 左子树不为空,中序左子树最后一个
			Node* rightMost = _node->_left;
			while (rightMost->_right)
			{
				rightMost = rightMost->_right;
			}
			_node = rightMost;
		}
		else
		{
			// 孩子是父亲右的那个祖先
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_left)
			{
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}

		return *this;
	}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

3 注意须知 [实现map/set]

set的iterator也不⽀持修改,我们把set的第⼆个模板参数改成const K即可, RBTree _t;

• map的iterator不⽀持修改key但是可以修改value,我们把map的第⼆个模板参数pair的第⼀个参数改成const K即可, RBTree, MapKeyOfT> _t;

3.1 map[]实现

map要⽀持[]主要需要修改insert返回值⽀持,修改RBtree中的insert返回值为

V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert({ key, V() });
			return ret.first->second;
		}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

3.2代码实现

//map.h
	template<class K, class V>
	class map
	{
		struct mapKeyofpair
		{
		   const K& operator()(const pair<K,V>& kv)
			    {
				return kv.first;
			    }
		};

	public:
		typedef typename RBtree<K, pair<const K, V>, mapKeyofpair>::Iterator iterator;
		typedef typename RBtree<K, pair<const K, V>, mapKeyofpair>::ConstIterator 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); 
		}

	private:
		RBtree<K, pair<const K, V>, mapKeyofpair> _t ;
	};
	//set.h
	template<class K>
	class set
	{
		struct setKeyofpair
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		typedef typename RBtree<K, const K, setKeyofpair>::Iterator iterator; 
		typedef typename RBtree<K, const K, setKeyofpair>::ConstIterator 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 K& data)
		{
			return _t.insert(data);
		}

	private:
		RBtree<K,const K, setKeyofpair> _t;
	};
	//RBtree.h
	enum Colour
{
	RED,
	BLACK
};




//红黑树结点
template<class T>
struct RBTreeNode
{
	// 这里更新控制平衡也要加入parent指针
	T _data;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	Colour _col;

	RBTreeNode(const T& data)
		: _data(data)
		, _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;

	Node* _node;
	Node* _root;


	RBtreeIterator(Node* node, Node* root)
		:_node(node)
		, _root(root)
	{}

	Self operator++() 
	{
		if (_node->_right)
		{
			// 右不为空,中序下一个访问的节点是右子树的最左(最小)节点
			Node* min = _node->_right;
			while (min->_left)
			{
				min = min->_left;
			}

			_node = min; 
		}
		else
		{
			// 右为空,祖先里面孩子是父亲左的那个祖先
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = cur->_parent;
			}

			_node = parent;
		}

		return *this;
	}

	Self operator--()
	{
		if (_node == nullptr)  // --end()
		{
			// --end(),特殊处理,走到中序最后一个结点,整棵树的最右结点
			Node* rightMost = _root;
			while (rightMost && rightMost->_right)
			{
				rightMost = rightMost->_right;
			}
			_node = rightMost;
		}
		else if (_node->_left)
		{
			// 左子树不为空,中序左子树最后一个
			Node* rightMost = _node->_left;
			while (rightMost->_right)
			{
				rightMost = rightMost->_right;
			}
			_node = rightMost;
		}
		else
		{
			// 孩子是父亲右的那个祖先
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_left)
			{
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}

		return *this;
	}

	Ref operator*()
	{
		return _node->_data;
	}

	Ptr operator->()
	{
		return &_node->_data;
	}

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

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

	template<class K, class T,class Keyofpair>
class RBtree
{
	typedef RBTreeNode<T> Node;
public:
	typedef RBtreeIterator<T, T&, T*> Iterator; 
	typedef RBtreeIterator<T, const T&, const T*> ConstIterator;





	Iterator begin()
	{
		Node* node = _root;
		while (node && node->_left) 
		{
			node = node->_left;
		}

		return Iterator(node,_root);
	}
	ConstIterator begin() const
	{
		Node* node = _root;
		while (node && node->_left)
		{
			node = node->_left;
		}

		return ConstIterator(node,_root);
	}

	Iterator end()
	{
		return Iterator(nullptr,_root);
	}

	ConstIterator end() const
	{
		return ConstIterator(nullptr,_root); 
	}



	pair<Iterator, bool> insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return{ Iterator(_root, _root), true };
		}
		Keyofpair com; 
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur)
		{
			if (com(cur->_data) < com(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (com(cur->_data) > com(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return { Iterator(cur, _root), false }; 
			}
		}

		cur = new Node(data);
		Node* newnode = cur;  
		cur->_col = RED;
		if (com(parent->_data) < com(data))
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;
		while (parent && parent->_col == RED)
		{
			Node* grandparent = parent->_parent;
			if (parent == grandparent->_left)
			{
				//   g
				// p   u
				Node* uncle = grandparent->_right;
				if (uncle && uncle->_col == RED)
				{
					// 变色
					parent->_col = uncle->_col = BLACK;
					grandparent->_col = RED;

					// 继续往上处理
					cur = grandparent;
					parent = cur->_parent;
				}
				else
				{
					if (cur == parent->_left)
					{
						//     g
						//   p    u
						// c
						RotateR(grandparent);
						parent->_col = BLACK;
						grandparent->_col = RED;
					}
					else
					{
						//      g
						//   p    u
						//     c
						RotateL(parent);
						RotateR(grandparent);
						cur->_col = BLACK;
						grandparent->_col = RED; 
					}

					break;
				}
			}
			else
			{
				Node* uncle = grandparent->_left;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandparent->_col = RED;

					// 继续往上处理
					cur = grandparent;
					parent = cur->_parent;
				}
				else
				{
					//旋转+变色
					if (cur == parent->_right)
					{
						//     g
					   //   u      p
					  //               c
						RotateL(grandparent); 
						parent->_col = BLACK; 
						grandparent->_col = RED;
					}
					else
					{
						//    g
					   // u       p
					  //      c
					 //需双旋+变色
						RotateR(parent);
						RotateL(grandparent);
						cur->_col = BLACK;
						grandparent->_col = RED;
					}
					break;//旋转完后根或者部分根是黑色的不用在意根之前是黑或是红或是空
				}
			}
		}
		_root->_col = BLACK;
		return { Iterator(newnode, _root), true }; 
	}
void RotateR(Node * parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

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

		Node* pParent = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

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

			subL->_parent = pParent;
		}
	}

	void RotateL(Node * parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;

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

	Node* Find(const K& key)
	{
		Node* cur = _root;
		while (cur)
		{
			if (cur->_kv.first < key)
			{
				cur = cur->_right;
			}
			else if (cur->_kv.first > key)
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}

		return nullptr;
	}

	int Height()
	{
		return _Height(_root);
	}

	int Size()
	{
		return _Size(_root);
	}

private:
	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;
	}

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

		return _Size(root->_left) + _Size(root->_right) + 1;
	}

private:
	Node* _root = nullptr;
};
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

最后在这悠长的叙述即将抵达彼岸之时,愿以一曲未了的旋律,轻拂你心灵的涟漪。我们共同走过的这段旅程,如同繁星点缀的夜空,每一颗星辰都承载着故事,每一缕光芒都映照着心迹。此刻,虽言尽而意未尽,但愿这份文字的余温,能伴你度过未来的每一个静!!!

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/2301_80109683/article/details/145228408","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的sdzdwa的文章"https://blog.csdn.net/2301_80109683/article/details/145228408"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!