map和set的封装

map和set的封装

前面我们讲解了红黑树的插入与删除,STL库里面map和set底层用的就是红黑树,所以我们来模拟一下。首先我们要确认一件事,我们红黑树,模版参数是这样的:template<class K>,或者 template<class K,class V>,那么如果我们要实现map和set的话需要写两个吗?那显然不是。来看一下STL库中是如何实现的:

在这里插入图片描述

库中是通过上述过程传入两个模版参数进去,如果是map的话我们传入<Key,pair<Key,Value>>进去,如果是set传入<Key,Key>,这样的话我们map和set就可以使用同一个红黑树了,真真起作用的参数是红黑树中第二个参数Value它决定了我们究竟是map还是set

插入操作

无论是set还是map,我们插入都是通过Key去查找所插入的位置,但是上述封装方式我们的,我们节点的_data还有可能会是pair<K,V>,那我们插入比较的时候如果什么都不写的话就会使用默认的比较,pair<>默认比较是先比较first,如果first相等再比较second,这样的话就不是通过Key去比较了,所以我们为了方便比较,在封装map和set的时候需要再写一个KeyOfVal类,如果我们是Key那么直接返回Key,如果是pair<>就返回pair<>.first去比较。

在这里插入图片描述

普通迭代器

迭代器结构:

为了方便我们定义const迭代器,所以这里我们加入RefPtr来表示我们operator*operator->的返回值。同时我们迭代器在这里代表的其实就是节点的指针,所以我们直接浅拷贝即可。无需深拷贝。


由于mapset都属于容器,所以也支持迭代器遍历操作。同时mapset迭代器都是双向迭代器,所以支持++和–。mapset迭代器遍历的结果就是红黑树的中序遍历,所以是有序的,这也就是说我们begin()指向的是左子树的最左边。

operator++() 前置++

在这里插入图片描述

这里我们可以把it指向的位置当做左子树已经访问完了,把他当做根,左子树不用去看。

  • 如果右子树存在:继续去找最左节点当做下一个访问的节点。

  • 如果右子树不存在:那就说明当前子树已经访问完了,那么我们就需要往回退了,如何退呢?(当前位置表示cur,父节点表示p

注意上面我们是只要右子树存在就去右子树去找,那么当右子树不存在只要此时我们cur == p->_right,那就说明这里已经访问过了,继续往上退。

在这里插入图片描述

我们的头节点pHead的左右子树初始化时均指向自己,所以到达pHead也就停止了。

代码实现:

		//前置++
		//Self表示迭代器本身,我们++过后返回迭代器即可。
		Self& operator++()
		{
			if (_node->_right)
			{
				node* cur = _node->_right;
				while (cur && cur->_left)
				{
					cur = cur->_left;
				}
				_node = cur;
			}
			else
			{
				node* p = _node->_parent;
				node* cur = _node;
				while (p->_right == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return *this;
		}

begin()和end()

begin()这里代表的就是最左边的节点,代表中序遍历的第一个节点,所以这里用LeftMost()来获取,而end()这里直接传入pHead即可,在我们operaotr++实现的图中,我们最后的节点是pHead所以正好也是结束的位置。

代码:

//红黑树封装	
	Iterator Begin()
		{
			return Iterator(LeftMost());
		}

		Iterator End()
		{
			return Iterator(pHead);
		}

		Node* LeftMost() const 
		{
			return _LeftMost(pHead);
		}

		Node* _LeftMost(Node* head) const
		{
			Node* cur = head->_parent;
			while (cur != head && cur->_left)
			{
				cur = cur->_left;
			}
			return cur;
		}

至于这里的LeftMost()为什么要加const在下面我们实现const迭代器的时候再说。

operator–() 前置–

用法:

由于我们的end()指向的是pHead,所以–的时候我们需要特殊判断一下,如果是pHead那么直接返回RightMost()的迭代器即可。RightMost()代表的就是最右边的节点,那么此时我们的–和++操作是类似的。遍历顺序就为:右子树 -》 根 -》左子树it所在的位置都代表了此时我们的右子树已经访问完了。

  • 如果左子树存在:找到左子树的最右节点返回即可
  • 如果左子树不存在:那就代表了此时这颗子树我们已经访问完了,由于我们上一步是左子树存在去访问左子树,那么此时我们如果cur == p->_left的话就继续往上调整就可以了。

在这里插入图片描述

代码实现:

Self& operator--()
		{
			if (_node && _node->_col == RED && _node->_parent->_parent == _node)
			{
                //RightMost的逻辑
				node* cur = _node->_parent;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else if (_node->_left)
			{
				node* cur = _node->_left;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else
			{
				node* cur = _node;
				node* p = cur->_parent;
				while (p->_left == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return *this;
		}

const迭代器

在这里插入图片描述

const迭代器使用场景:

void Print1(const S::MySet<int> & vv)

如上,如果要求我们打印一边数据呢,此时我们的数据元素不可修改,那么此时我们就需要使用const迭代器了。

定义:

在这里插入图片描述

这里主要来说一下为什么需要加这个const,正常情况下我们this指针的类型为 classname(类名)* const这代表着我们this指针的指向不可改变,当我们加入了const修饰后,this指针的类型为 classname(类名) const * const 这代表着我们this指针的指向和指向的值都不能改变。

如果我们LeftMost()不加const修饰的话,先插一句,C++为什么我们对象实例化之后只需要调用对应的访问函数即可,是因为这个this指针是编译器帮我们加上了,所以此时我们的括号里面其实就有一个(objectname(实例化的对象)& const ,好回到刚才,如果我们LeftMost()不加const修饰的话,我们const迭代器括号里面的为objectname const& const ,而LeftMost()如果没有迭代器括号里面为objectname & const ,那么此时就相当于是本来不可以修改又变为可以修改这属于权限的放大,所以编译都过不了,所以我们要给LeftMost加一个const修饰。

map和set封装代码

在这里插入图片描述

这里顺便提一下,在模版当中,当我们需要指定类域去使用里面的内容时,需要指定类型,这个在模版进阶中提到过。

set

template<class K>
	class MySet
	{
	public:
		struct SetKeyOfVal
		{
			const K& operator()(const K& x)
			{
				return x;
			}
		};

		typedef  RBT::RBTree<K, K, SetKeyOfVal> t;
		typedef RBT::RBTreeNode<K> node;
		typedef typename RBT::RBTreeIterator<K, K&, K*> iterator;
		typedef typename RBT::RBTreeIterator<K,const K&,const K*> const_iterator;

		typedef typename RBT::RBTreeReverseIterator<K, K&, K*> reverse_iterator;
		typedef typename RBT::RBTreeReverseIterator<K, const K&, const K*> const_reverse_iterator;

		MySet() = default;

		reverse_iterator rbegin()
		{

			return _node.RBegin();
		}

		reverse_iterator rend()
		{
			return _node.REnd();
		}

		const_reverse_iterator rcend()  const
		{
			return _node.RCEnd();
		}

		const_iterator cbegin() const
		{
			return _node.CBegin();
		}

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

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

		// Data* const this
		// &_node
		const_reverse_iterator rcbegin() const
		{
			return _node.RCBegin();
		}

		

		const_iterator cend()  const
		{
			return _node.CEnd();
		}
		void erase(iterator pos)
		{
			_node.erase(pos._node->_data);
		}

		pair<iterator,bool> insert(const K& key)
		{
			return _node.insert(key);
		}

		node* Getroot()
		{
			return _node.GetRoot();
		}

		void clear()
		{
			_Destory(_node.GetRoot()->_parent);
			_node.GetRoot()->_parent = nullptr;
		}

		void swap(MySet<K>& x)
		{
			node* newroot = x.Getroot();
			node* root = _node.GetRoot();
			std::swap(root->_parent,newroot->_parent);
			std::swap(root->_parent->_parent,newroot->_parent->_parent);
		}

		bool empty()
		{
			return _node.Empty();
		}

		int size()
		{
			return _node.Size();
		}

		void inorder()
		{
			_node.inorder();
		}

		bool IsRBTree()
		{
			return _node.IsRBTree();
		}
		
	private:
		t _node;

		void _Destory(node* root)
		{
			if (root == nullptr || root == _node.GetRoot())
				return;
			_Destory(root->_left);
			_Destory(root->_right);
			root->_parent = nullptr;
			delete root;
			root = nullptr;
		}
	};

map

enum Color
	{
		RED,
		BLACK
	};

	template<class K,class V>
	class Mymap
	{
	public:
		struct MapKeyOfVal
		{
			const K& operator()(const pair<K, V>& x)
			{
				return x.first;
			}
		};

		typedef  RBT::RBTree<K, pair<K,V>, MapKeyOfVal> t;
		typedef RBT::RBTreeNode<pair<K, V>> node;
		typedef typename RBT::RBTreeIterator<pair<K, V>, pair<K, V>&, pair<K, V>*> iterator;
		typedef typename RBT::RBTreeIterator<pair<K, V>, const pair<K, V>&, const pair<K, V>*> const_iterator;

		typedef typename RBT::RBTreeReverseIterator<pair<K, V>, pair<K, V>&, pair<K, V>*> reverse_iterator;
		typedef typename RBT::RBTreeReverseIterator<pair<K, V>, pair<K, V>&, pair<K, V>*> const_reverse_iterator;

		Mymap() = default;


		void erase(iterator pos)
		{
			_node.erase(pos._node->_data);
		}

		V& operator[](const K& key)
		{
			return  (*((_node.insert(make_pair(key,K()))).first)).second;
		}

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

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

		const_iterator cbegin() const
		{
			return _node.CBegin();
		}

		const_iterator cend() const
		{
			return _node.CEnd();
		}

		reverse_iterator rbegin()
		{

			return _node.RBegin();
		}

		reverse_iterator rend()
		{
			return _node.REnd();
		}

		const_reverse_iterator rcend()  const
		{
			return _node.RCEnd();
		}

		const_iterator rcbegin() const
		{
			return _node.RCBegin();
		}

		pair<iterator,bool> insert(const pair<K,V>& data)
		{
			return _node.insert(data);
		}

		node* Getroot()
		{
			return _node.GetRoot();
		}

		void swap(Mymap<K,V>& x)
		{
			node* newroot = x.Getroot();
			node* root = _node.GetRoot();
			std::swap(root->_parent, newroot->_parent);
			std::swap(root->_parent->_parent, newroot->_parent->_parent);
		}

		bool empty()
		{
			return _node.Empty();
		}
		void inorder()
		{
			node* root = _node.GetRoot();
			_Inorder(root->_parent);
			
		}

		void clear()
		{
			_Destory(_node.GetRoot()->_parent);
			_node.GetRoot()->_parent = nullptr;
		}

		bool IsRBTree()
		{
			return _node.IsRBTree();
		}

		int size()
		{
			return _node.Size();
		}

	private:
		void _Inorder(node* root)
		{
			if (root == nullptr || (root && root->_col == RED && root->_parent->_parent == root))
				return;

			_Inorder(root->_left);
			cout << root->_data.first << " : " << root->_data.second << endl;
			_Inorder(root->_right);
		}

		void _Destory(node* root)
		{
			if (root == nullptr || root == _node.GetRoot())
				return;
			_Destory(root->_left);
			_Destory(root->_right);
			root->_parent = nullptr;
			delete root;
			root = nullptr;
		}

		t _node;


	};

RBTree

enum Color
	{
		RED,
		BLACK
	};

	template<class K>
	struct RBTreeNode
	{
		K _data;
		RBTreeNode<K>* _left;
		RBTreeNode<K>* _right;
		RBTreeNode<K>* _parent;
		Color _col;

		RBTreeNode(const K& key)
			:_data(key)
			, _left(nullptr)
			, _right(nullptr)
			, _parent(nullptr)
			,_col(RED)
		{}

		~RBTreeNode()
		{
			_data = K();
			_left = _right = _parent = nullptr;
		}
	};

	template<class K, class Ref, class Ptr>
	struct RBTreeReverseIterator
	{
		typedef RBTreeReverseIterator<K, Ref, Ptr> Self;
		typedef RBTreeNode<K> node;
		node* _node;

		//RBTreeIterator() = default;

		RBTreeReverseIterator(node* root)
			:_node(root)
		{}

		//reverse迭代器的++
		Self& operator++()
		{
			if (_node && _node->_col == RED && _node->_parent->_parent == _node)
			{
				node* cur = _node->_parent;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else if (_node->_left)
			{
				node* cur = _node->_left;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else
			{
				node* cur = _node;
				node* p = cur->_parent;
				while (p->_left == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return *this;
		}

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

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

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

	};



	template<class K,class Ref,class Ptr>
	struct RBTreeIterator
	{
		typedef RBTreeIterator<K,Ref,Ptr> Self;
		typedef RBTreeNode<K> node;
		node* _node;

		//RBTreeIterator() = default;

		RBTreeIterator(node* root)
			:_node(root)
		{}

		//前置++
		Self& operator++()
		{
			if (_node->_right)
			{
				node* cur = _node->_right;
				while (cur && cur->_left)
				{
					cur = cur->_left;
				}
				_node = cur;
			}
			else
			{
				node* p = _node->_parent;
				node* cur = _node;
				while (p->_right == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return *this;
		}

		Self operator++(int)
		{
			Self tmp(_node);
			if (_node->_right)
			{
				node* cur = _node->_right;
				while (cur && cur->_left)
				{
					cur = cur->_left;
				}
				_node = cur;
			}
			else
			{
				node* p = _node->_parent;
				node* cur = _node;
				while (p->_right == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return tmp;
		}

		Self& operator--()
		{
			if (_node && _node->_col == RED && _node->_parent->_parent == _node)
			{
				node* cur = _node->_parent;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else if (_node->_left)
			{
				node* cur = _node->_left;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else
			{
				node* cur = _node;
				node* p = cur->_parent;
				while (p->_left == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return *this;
		}

		Self operator--(int)
		{
			Self tmp(_node);
			if (_node && _node->_col == RED && _node->_parent->_parent == _node)
			{
				node* cur = _node->_parent;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else if (_node->_left)
			{
				node* cur = _node->_left;
				while (cur && cur->_right)
				{
					cur = cur->_right;
				}
				_node = cur;
			}
			else
			{
				node* cur = _node;
				node* p = cur->_parent;
				while (p->_left == cur)
				{
					cur = p;
					p = cur->_parent;
				}
				_node = p;
			}
			return tmp;
		}

		Ref operator*()
		{
			if (_node->_col == RED && _node->_parent->_parent == _node)
				assert(false);
			return _node->_data;
		}

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

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

	};

	template<class K,class V,class KeyOfVal>
	class RBTree
	{
	public:
		typedef RBTreeNode<V> Node;
		typedef RBTreeIterator<V, V&, V*> Iterator;
		typedef RBTreeIterator<V,const V&,const V*> ConstIterator;
	

		typedef RBTreeReverseIterator<V, V&, V*> ReverseIterator;
		typedef RBTreeReverseIterator<V, const V&, const V*> ConstReverseIterator;
		//class K, class Ref, class Ptr

		Iterator Begin()
		{
			return Iterator(LeftMost());
		}

		Iterator End()
		{
			return Iterator(pHead);
		}


		ReverseIterator RBegin()
		{
			return ReverseIterator(RightMost());
		}

		ReverseIterator REnd()
		{
			return ReverseIterator(pHead);
		}

		ConstReverseIterator RCBegin() const
		{
			return ConstReverseIterator(RightMost());
		}

		ConstReverseIterator RCEnd() const
		{
			return ConstReverseIterator(pHead);
		}

		ConstIterator CBegin() const
		{
			return ConstIterator(LeftMost());
		}

		ConstIterator CEnd() const
		{
			return ConstIterator(pHead);
		}

		Node* LeftMost() const
		{
			return _LeftMost(pHead);
		}

		Node* RightMost() const
		{
			return _RightMost(pHead);
		}


		bool Empty()
		{
			return pHead->_parent == pHead;
		}

		RBTree()
		{
			//创建头节点
			pHead =  CreatNode();
		}

		~RBTree()
		{
			_Destory(pHead->_parent);
			delete pHead;
			pHead = nullptr;
		}

		RBTree(const RBTree<K,V, KeyOfVal>& tree)
		{
			pHead = CreatNode();
			pHead->_parent = _Copy(tree.pHead->_parent);
		}

		void inorder()
		{
			_Inorder(pHead->_parent);
			cout << endl;
		}

		//左单旋
		void RotateL(Node* parent)
		{
			Node* pparent = parent->_parent;
			Node* child = parent->_right;
			Node* childLeft = child->_left;

			parent->_right = childLeft;

			if (childLeft) //可能为空
				childLeft->_parent = parent;

			child->_left = parent;

			//更新父节点的连接
			if (pparent != pHead) //如果原parent的父节点不为空
			{
				if (pparent->_left == parent)
				{
					pparent->_left = child;
				}
				else
				{
					pparent->_right = child;
				}
				//别忘了child的父节点
				child->_parent = pparent;
			}
			else //说明旋转的是根节点
			{
				child->_parent = pHead;
				pHead->_parent = child;
			}

			parent->_parent = child;
		}

		//右单旋
		void RotateR(Node* parent)
		{
			Node* pparent = parent->_parent;
			Node* child = parent->_left;
			Node* childRight = child->_right;

			parent->_left = childRight;
			if (childRight) //可能为空
				childRight->_parent = parent;

			child->_right = parent;

			//更新父节点的连接
			if (pparent != pHead) //如果原parent的父节点不为哨兵节点
			{
				if (pparent->_left == parent)
				{
					pparent->_left = child;
				}
				else
				{
					pparent->_right = child;
				}
				//别忘了child的父节点
				child->_parent = pparent;
			}
			else //说明旋转的是根节点
			{
				child->_parent = pHead;
				pHead->_parent = child;
			}
			parent->_parent = child;
		}

		

		pair<Iterator,bool> insert(const V& key)
		{
			KeyOfVal kot;
			//只有一个头节点
			if (pHead->_parent == pHead)
			{
				pHead->_parent = new Node(key);
				pHead->_parent->_parent = pHead;
				pHead->_parent->_col = BLACK;
				return {Iterator(pHead->_parent),true};
			}
			Node* cur = pHead->_parent;
			Node* parent = cur->_parent;
			while (cur)
			{
				if (kot(key) < kot(cur->_data))
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (kot(key) > kot(cur->_data))
				{
					parent = cur;
					cur = cur->_right;
				}
				else
					return {Iterator(cur),false};
			}
			cur = new Node(key);
			cur->_parent = parent;
			//连接新增节点与父节点的关系
			if (parent->_data > key)
				parent->_left = cur;
			else
				parent->_right = cur;

			Iterator ret = Iterator(cur);
			Node* grandfather = parent->_parent;
			Node* uncle = nullptr;
			//满足parent的颜色是红色节点 并且 parent不是哨兵节点。
			while (parent->_col == RED && parent != pHead)
			{
				if (grandfather->_left == parent)
					uncle = grandfather->_right;
				else
					uncle = grandfather->_left;

				if (uncle && uncle->_col == RED) //p红色,u红色
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;
					cur = grandfather;
					parent = grandfather->_parent;
					grandfather = parent->_parent;
				}
				else if ((uncle && uncle->_col == BLACK) || uncle == nullptr)
				{
					//右单旋
					if (grandfather->_left == parent && parent->_left == cur)
					{
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else if (grandfather->_right == parent && parent->_right == cur)
					{
						//左单旋
						RotateL(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else if (grandfather->_left == parent && parent->_right == cur)
					{
						//左右双旋
						RotateL(parent);
						RotateR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					else if (grandfather->_right == parent && parent->_left == cur)
					{
						//右左双旋
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
				else
				{
					assert(false);
				}
			}
			pHead->_parent->_col = BLACK;
			return { ret,true};
		}

		//进来的都是叶子节点为黑色的情况,那么如果叶子节点为黑色的话,一定有兄弟节点。不然违反了性质4.
		void ChangeColor(Node* cur, Node* parent)
		{
			Node* uncle = nullptr;
			//1. 如果uncle是黑色节点,并且它有红色的孩子节点(旋转的状态)
			//2. 如果uncle是黑色节点,并且他的孩子都是黑色节点(NULL也算),那么就把兄弟节点变为红色同时向上遍历双重黑色节点
			//3. 如果uncle是红色节点,交换兄弟和parent的颜色,然后向删除节点的方向旋转,然后继续观察兄弟节点
			while (parent != pHead)
			{
				if (parent->_left == cur)
				{
					uncle = parent->_right;
				}
				else
				{
					uncle = parent->_left;
				}

				if (uncle->_col == BLACK)
				{
					//进行右单旋
					if (parent->_left == uncle && uncle->_left && uncle->_left->_col == RED)
					{
						Node* uncle_left = uncle->_left;
						//变色
						uncle_left->_col = uncle->_col;
						uncle->_col = parent->_col;
						parent->_col = BLACK;
						//旋转
						RotateR(parent);
						break;
					}
					else if (parent->_right == uncle && uncle->_right && uncle->_right->_col == RED)
					{
						//进行左单旋
						Node* uncle_right = uncle->_right;
						//变色
						uncle_right->_col = uncle->_col;
						uncle->_col = parent->_col;
						parent->_col = BLACK;
						RotateL(parent);
						break;
					}
					else if (parent->_left == uncle && uncle->_right && uncle->_right->_col == RED)
					{
						//进行左右双旋
						Node* uncle_right = uncle->_right;
						//变色
						uncle_right->_col = parent->_col;
						parent->_col = BLACK;
						RotateL(uncle);
						RotateR(parent);
						break;
					}
					else if (parent->_right == uncle && uncle->_left && uncle->_left->_col == RED)
					{
						//进行右左双旋
						Node* uncle_left = uncle->_left;
						//变色
						uncle_left->_col = parent->_col;
						parent->_col = BLACK;
						RotateR(uncle);
						RotateL(parent);
						break;
					}
					else if ((uncle->_left == nullptr && uncle->_right == nullptr) || (uncle->_left && uncle->_right && uncle->_left->_col == BLACK && uncle->_right->_col == BLACK))
					{
						//兄弟节点的孩子全为黑色节点
						//把兄弟节点变为红色,然后双重黑色节点往上调继续遍历
						uncle->_col = RED;
						//遍历到根节点或者红色节点把节点变为黑色退出即可。
						if ((uncle->_parent != pHead->_parent && uncle->_parent->_col == RED) || (uncle->_parent == pHead->_parent))
						{
							uncle->_parent->_col = BLACK;
							break;
						}
						else
						{
							cur = uncle->_parent;
							parent = cur->_parent;
						}
					}

				}
				else if (uncle->_col == RED)
				{
					//交换uncle和parent的颜色,Parent变为黑色,然后向删除节点方向旋转,再看双重黑节点

					uncle->_col = parent->_col;
					parent->_col = RED;
					if (parent->_left == cur)
					{
						RotateL(parent);
					}
					else
					{
						RotateR(parent);
					}
					cur = cur;
					parent = cur->_parent;
				}

			}



		}

		bool erase(const V& key)
		{
			KeyOfVal kot;
			//只有一个哨兵节点无法删除。
			if (pHead->_parent == pHead)
				return false;
			Node* cur = pHead->_parent;
			Node* parent = pHead;
			while (cur)
			{
				if (kot(key) < kot(cur->_data))
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (kot(key) > kot(cur->_data))
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					//叶子节点
					if (cur->_left == nullptr && cur->_right == nullptr)
					{
						//如果删除的是根节点,直接让哨兵的parent指针指向自己。
						if (parent == pHead)
						{
							pHead->_parent = pHead;
							delete cur;
							return true;
						}
						else if (cur->_col == RED)//红色的话直接删除
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
							delete cur;
							return true;
						}
						else if (cur->_col == BLACK) //如果删除的节点为黑色节点
						{
							ChangeColor(cur,parent);
							if (parent->_left == cur)
								parent->_left = nullptr;
							else
								parent->_right = nullptr;
							delete cur;

							return true;
						}
					}
					else if (cur->_left == nullptr) //左边为空
					{
						//删除的为根节点,直接改变pHead的指向即可。
						if (parent == pHead)
						{
							pHead->_parent = cur->_right;
							if (cur->_right)
							{
								cur->_right->_col = BLACK;
								cur->_right->_parent = pHead;
							}
							delete cur;
							return true;
						}
						else if (cur->_col == BLACK)
						{
							//判断为父亲节点的哪一边
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
							//如果删除的单孩子节点为黑色,就需要把删除节点的右孩子变为黑色。如果有右孩子的话)
							if (cur->_right)
							{
								cur->_right->_col = BLACK;
								cur->_right->_parent = parent; //如果有的话别忘了连接父节点
							}
							delete cur;
							return true;
						}
						else if (cur->_col == RED)
						{
							//判断为父亲节点的哪一边
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
							//如果删除的单孩子节点为红色,直接删除
							delete cur;
							return true;
						}
					}
					else if (cur->_right == nullptr)
					{
						//删除的为根节点,直接改变pHead的指向即可。
						if (parent == pHead)
						{
							pHead->_parent = cur->_left;
							if (cur->_left)
							{
								cur->_left->_col = BLACK;
								cur->_left->_parent = pHead;
							}
							delete cur;
							cur = nullptr;
							return true;
						}
						else if (cur->_col == BLACK)
						{
							//判断为父亲节点的哪一边
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
							//如果删除的单孩子节点为黑色,就需要把删除节点的左孩子变为黑色(如果有左孩子的话)
							if (cur->_left)
							{
								cur->_left->_col = BLACK;
								cur->_left->_parent = parent;

							}
							delete cur;
							cur = nullptr;
							return true;
						}
						else if (cur->_col == RED)
						{
							//判断为父亲节点的哪一边
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
							//如果删除的单孩子节点为红色,直接删除
							delete cur;
							cur = nullptr;
							return true;
						}
					}
					else //双孩子节点
					{
						//如果删除节点为红色
						if (cur->_col == RED)
						{
							Node* RightMinP = cur;
							Node* RightMin = cur->_right;
							while (RightMin && RightMin->_left)
							{
								RightMinP = RightMin;
								RightMin = RightMin->_left;
							}
							cur->_data = RightMin->_data;
							//如果RightMin的颜色为黑色
							if (RightMin->_col == BLACK)
							{
								//如果RightMin有右孩子,那么一定为红色的,删除RightMin之后要把他的右孩子变为黑色。

								if (RightMin->_right)
								{
									RightMin->_right->_col = BLACK;
									RightMin->_right->_parent = RightMinP;

									// 如果有红色节点的uha,直接连接并且赋值为黑色
									if (RightMinP->_left == RightMin)
									{
										RightMinP->_left = RightMin->_right;
									}
									else
									{
										RightMinP->_right = RightMin->_right;
									}
									delete RightMin;
								}
								
							
								
								else //如果没有的话那么转化为删除黑色叶子节点
								{
									ChangeColor(RightMin, RightMinP);
									if (RightMinP->_left == RightMin)
									{
										RightMinP->_left = nullptr;
									}
									else
									{
										RightMinP->_right = nullptr;
									}
									delete RightMin;
								}
							
								return true;
							}
							else//如果RightMin的颜色为红色,直接删除,连接右孩子
							{
								if (RightMinP->_left == RightMin)
								{
									RightMinP->_left = RightMin->_right;
								}
								else
								{
									RightMinP->_right = RightMin->_right;
								}

								if (RightMin->_right)
								{
									RightMin->_right->_parent = RightMinP;
								}
								delete RightMin;
								return true;
							}
						
						}
						else//如果删除节点为黑色
						{
							Node* RightMinP = cur;
							Node* RightMin = cur->_right;
							while (RightMin && RightMin->_left)
							{
								RightMinP = RightMin;
								RightMin = RightMin->_left;
							}
							cur->_data = RightMin->_data;
							//如果RightMin的颜色为黑色
							if (RightMin->_col == BLACK)
							{

								if (RightMin->_right)
								{
									//如果RightMin有右孩子,那么一定为红色的,删除RightMin之后要把他的右孩子变为黑色。

									RightMin->_right->_col = BLACK;
									RightMin->_right->_parent = RightMinP;

									if (RightMinP->_left == RightMin)
									{
										RightMinP->_left = RightMin->_right;
									}
									else
									{
										RightMinP->_right = RightMin->_right;
									}
									delete RightMin;
									return true;
								}
								
								else //如果没有的话那么转化为删除黑色叶子节点
								{
									ChangeColor(RightMin, RightMinP);
									if (RightMinP->_left == RightMin)
									{
										RightMinP->_left = nullptr;
									}
									else
									{
										RightMinP->_right = nullptr;
									}
									delete RightMin;
								}
								return true;
							}
							else//如果RightMin的颜色为红色,直接删除,连接右孩子
							{
								if (RightMinP->_left == RightMin)
								{
									RightMinP->_left = RightMin->_right;
								}
								else
								{
									RightMinP->_right = RightMin->_right;
								}
								if (RightMin->_right)
								{
									RightMin->_right->_parent = RightMinP;
								}
								delete RightMin;

								return true;
							}
						}
					}
				}
			}
			return false;
		}
		Node* find(const K& val)
		{
			if (pHead->_parent == pHead)
				return pHead;
			Node* cur = pHead->_parent;
			while (cur)
			{
				if (KeyOfVal(val) < KeyOfVal(cur->_data))
					cur = cur->_left;
				else if (KeyOfVal(val) > KeyOfVal(cur->_data))
					cur = cur->_right;
				else
					return cur;
			}
			return pHead;
		}

		bool IsRBTree()
		{
			return _isRBTree(pHead->_parent);
		}

		int Height()
		{
			return TreeHigh(pHead->_parent);
		}

		int Size()
		{
			return _size(pHead->_parent);
		}

		Node* GetRoot()
		{
			return pHead;
		}

	private:

		int _size(Node* root)
		{
			if (root == pHead || root == nullptr)
				return 0;
			return _size(root->_left) + _size(root->_right) + 1;
		}
		int TreeHigh(Node* root)
		{
			if (root == nullptr || root->_parent == root)
				return 0;
			return max(TreeHigh(root->_left),TreeHigh(root->_right)) + 1;
		}

		bool _isRBTree(Node* root)
		{
			//只有一个头节点
			if (root->_parent == root)
				return true;
			Node* LeftMost = root;
			if (root->_col != BLACK)
			{
				cout << " 违反性质二:根节点为黑色 " << endl;
				return false;
			}
			int k = 0;
			while (LeftMost)
			{
				if (LeftMost->_col == BLACK)
					k++;
				LeftMost = LeftMost->_left;
			}
			return IsSameBlack(root->_left,1,k) && IsSameBlack(root->_right, 1, k);
		}

		bool IsSameBlack(Node* root, size_t cnt, int k)
		{
			if (root == nullptr)
			{
				cout << "当前路径黑色节点数量:" << cnt << endl;
				if (cnt != k)
				{
					cout << "违反性质四:每条路径中的黑色节点数量不一样 " << endl;
					return false;
				}
				return true;
			}
			if (root->_col == BLACK)
				cnt++;
			Node* parent = root->_parent;
			if (parent != pHead && parent->_col == RED && root->_col == RED)
			{
				cout << " 违反性质三:不能有连续的红色节点" << endl;
				return false;
			}
			return IsSameBlack(root->_left, cnt, k) && 
			IsSameBlack(root->_right, cnt, k);
		}

		Node* _LeftMost(Node* head) const
		{
			Node* cur = head->_parent;
			while (cur != head && cur->_left)
			{
				cur = cur->_left;
			}
			return cur;
		}

		Node* _RightMost(Node* head) const
		{
			Node* cur = head->_parent;
			while (cur != head && cur->_right)
			{
				cur = cur->_right;
			}
			return cur;
		}


		Node* CreatNode()
		{
			Node* node = new Node(V());
			node->_left = node;
			node->_right = node;
			node->_parent = node;
			return node;
		}



		Node* _Copy(Node* root)
		{
			if (root == nullptr)
				return nullptr;
			Node* newRoot = new Node(root->_data);
			newRoot->_col = root->_col;
			Node* left = _Copy(root->_left);
			Node* right = _Copy(root->_right);
			if (left)
				left->_parent = newRoot;
			if (right)
				right->_parent = newRoot;
			newRoot->_left = left;
			newRoot->_right = right;
			return newRoot;
		}
		void _Destory(Node* root)
		{
			if (root == nullptr || root == pHead)
				return;
			_Destory(root->_left);
			_Destory(root->_right);
			delete root;
			root = nullptr;
		}
		void _Inorder(Node* root)
		{
			if (root == pHead || root == nullptr)
				return;

			_Inorder(root->_left);
			cout << root->_data << " : " << root->_col << endl;
			_Inorder(root->_right);
		}
		Node* pHead;
	};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值