map set


前言:

  • 想了解map与set就得先知道其是由 平衡搜索二叉树 为底层实现的一种数据结构,与二叉搜索树不同的是其就有自我调节高度能力(当然是需要我们写代码维护其性质)
  • 常见的平衡二叉树有两种 AVLTree , 红黑树(RBTree)
  • 为什么不用 二叉搜索树 呢?因为其如果插入的数据为有序时会成为单链表的形态,查找数据时,时间复杂度退化成 O(N)
  • 平衡二叉搜索树 对每一次的插入数据就会进行判断是否需要调节,每棵树具体的调节方式下文讲解

Ⅰ. AVLTree

前言:

  • AVLTree 是由两位俄罗斯的数学家 G.M.Adelson-Velskii 和 E.M.Landis 在1962年提出的,为解决二叉搜索树的退化成链表问题而孕育而生的
  • AVLTree 是保证左右子树的高度差在 -1 <= 右高度 - 左高度 <= 1 的范围内,这样就可以降低树的高度,从而降低树的平均查找长度
  • 根据定义,插入若 插入其右其 右- 左 的高度差 + + ,插入其左 右 - 左 的高度差 - - ,若不在规定的范围就需要调整,就是所谓的旋转,将子或父旋转到祖父的位置
  • 考虑一下插入的情况一共有几种? 先分大方向,要么插入到根的 左子树或者右子树,其两棵树高度如果相等,随便插入无需理会
  • 若插入 较高左子树 可插入左边右边
  • 若插入 较高右子树 可插入左边右边
// 节点声明
template<class K,class V>
struct TreeNode
{
	TreeNode<K,V>* _left;
	TreeNode<K,V>* _right;
	TreeNode<K,V>* _parent;
	pair<K, V> _kv;

	int _bf;

	TreeNode(const pair<K,V> kv)
		:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0)
	{}
};

1. 插入右旋

较高左子树的左插入
在这里插入图片描述

首先解释一下为什么这一幅图片就可以代表 左旋的 所有情况:

  1. 若a b 高度不同,对于30 来说 是不是又会被细分为 大方向上的 四种情况? 即左右子树较高的左右侧插入
  2. 若无30节点,那60的左右子树高度相等 即意味着 随便插入也不会导致平衡高度因子变为超出范围,故无需旋转
  3. 若a b c 树的高度不同
    a. a b 小于c一层 加上30后高度与c相等,重回2情况
    b. a b 大于c一层60的平衡因子超出范围,为-2 ,故等不到新节点的插入,其就不平衡了,就意味着插入之前就得调节平衡了

在这里插入图片描述
接下来的操作就是将b作为60的左,而60作为30的右,这样就可以使其左右高度差为0

为什么可以这样旋转呢?
因为由二叉搜索树的性质 a < 30 < b < 60 < c
我让b作为60的左,c作为60的右不过分吧 ? 接着我让这棵新形成的树作为30 的右,a作为30的左也不过分吧?
这样旋转完成后,仍满足二叉搜索树的性质,这就是点睛之笔

void RotateR(Node* parent)
{
	Node* subL = parent->_left;
	Node* subLR = subL->_right;
	
	parent->_left = subLR;
	if(subLR) subLR->_parent = parent;

	Node* ppnode = parent->_parent;
	subL->_right = parent;
	parent->_parent = subL;

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

	parent->_bf = subL->_bf = 0;
}

2. 插入左旋

较高右子树的右插入
在这里插入图片描述
插入左旋同理可得:
在这里插入图片描述

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

	parent->_right = subRL;

	if (subRL) subRL->_parent = parent;

	Node* ppnode = parent->_parent;
	subR->_left = parent;
	parent->_parent = subR;

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

		subR->_parent = ppnode;
	}
	parent->_bf = subR->_bf = 0;
}

3. 插入左右双旋

插入较高左子树的右侧
可能右三种情况:
就是60本身(即h==0);
60的左边 (即h > 0)
60的右边 (即h > 0 )
为什么此时需要分三种情况? 因为单旋需要两次单旋,单旋30时会导致不同的子树进行重新组合,平衡因子的调节会有所不同
在这里插入图片描述
遇到不平衡,继续使用单旋,但是旋转过后发现仍然不平衡,所以这时候就不得不想其他方法了,单旋不行的原因大概就是,这棵树的左子树并不是单纯的一边高,这就好比child想上位,将parent压下来,但是给parent的手下太多了,child管不住,本身单旋是child的手下很多,给parent的手下很少,可以制约平衡,这时候就想将child给parent的手下先拿走一点,然后再进行单旋就行了,即对child的左单旋,然后再对parent右单旋
在这里插入图片描述

void RotateLR(Node* parent)
{
	Node* subL = parent->_left;
	Node* subLR = subL->_right;
	
	int bf = subLR->_bf;
	
	RotateL(subL);
	RotateR(parent);
	
	if (bf == 0)
	{
		parent->_bf = 0;
		subL->_bf = 0;
		subLR->_bf = 0;
	}
	else if (bf == 1)
	{
		parent->_bf = 0;
		subL->_bf = -1;
		subLR->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 1;
		subL->_bf = 0;
		subLR->_bf = 0;
	}
}

4. 插入右左双旋

在较高右子树的左侧插入
也分三种情况,自己,左子树内,右子树内
同理可得:
在这里插入图片描述

void RotateRL(Node* parent)
{
	Node* subR = parent->_right;
	Node* subRL = subR->_left;

	int bf = subRL->_bf;
	RotateR(subR);
	RotateL(parent);

	if (bf == 0)
	{
		parent->_bf = 0;
		subR->_bf = 0;
		subRL->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 0;
		subR->_bf = 1;
		subRL->_bf = 0;
	}
	else if (bf == 1)
	{
		subRL->_bf = 0;
		parent->_bf = -1;
		subR->_bf = 0;
	}
}

5. 底层实现

底层的实现

template<class K,class V>
struct TreeNode
{
	TreeNode<K,V>* _left;
	TreeNode<K,V>* _right;
	TreeNode<K,V>* _parent;
	pair<K, V> _kv;

	int _bf;

	TreeNode(const pair<K,V> kv)
		:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0)
	{}
};

template<class K,class V>
class AVLTree
{
	typedef TreeNode<K, V> Node;
public:
	bool insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			return true;
		}

		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kv.first < cur->_kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else if(kv.first > cur->_kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(kv);
		if (kv.first < parent->_kv.first) parent->_left = cur;
		else parent->_right = cur;
		cur->_parent = parent;

		while (parent)
		{
			if (cur == parent->_left) parent->_bf--;
			else parent->_bf++;

			if (parent->_bf == 0)
			{
				break;
			}
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
				cur = parent;
				parent = cur->_parent;
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
				if (parent->_bf == 2 && cur->_bf == 1)
				{
					RotateL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == -1)

				{
					RotateR(parent);
				}
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
					RotateRL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
					RotateLR(parent);
				}
				else
				{
					assert(false);
				}

				break;
			}
			else
			{
				assert(false);
			}
		}
		return true;
	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		
		parent->_left = subLR;
		if(subLR) subLR->_parent = parent;

		Node* ppnode = parent->_parent;
		subL->_right = parent;
		parent->_parent = subL;

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

		parent->_bf = subL->_bf = 0;
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;

		if (subRL) subRL->_parent = parent;

		Node* ppnode = parent->_parent;
		subR->_left = parent;
		parent->_parent = subR;

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

			subR->_parent = ppnode;
		}
		parent->_bf = subR->_bf = 0;
	}
	void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		
		int bf = subLR->_bf;
		
		RotateL(subL);
		RotateR(parent);
		
		if (bf == 0)
		{
			parent->_bf = 0;
			subL->_bf = 0;
			subLR->_bf = 0;
		}
		else if (bf == 1)
		{
			parent->_bf = 0;
			subL->_bf = -1;
			subLR->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 1;
			subL->_bf = 0;
			subLR->_bf = 0;
		}
	}
	void RotateRL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		int bf = subRL->_bf;
		RotateR(subR);
		RotateL(parent);

		if (bf == 0)
		{
			parent->_bf = 0;
			subR->_bf = 0;
			subRL->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			subR->_bf = 1;
			subRL->_bf = 0;
		}
		else if (bf == 1)
		{
			subRL->_bf = 0;
			parent->_bf = -1;
			subR->_bf = 0;
		}
	}
	void inorder()
	{
		_inorder(_root);
	}
	bool isbalance()
	{
		return _isbalance(_root);
	}
	int height()
	{
		return _height(_root);
	}
	int size()
	{
		return _size(_root);
	}
private:
	int _size(Node* root)
	{
		return root == nullptr ? 0 : _size(root->_left) + _size(root->_right) + 1;
	}
	void _inorder(Node* root)
	{
		if (root == nullptr) return;
		_inorder(root->_left);
		cout << root->_kv.first << "->" << root->_kv.second << endl;
		_inorder(root->_right);
	}
	int _height(Node* root)
	{
		if (root == nullptr) return 0;
		int left = _height(root->_left);
		int right = _height(root->_right);
		return max(left, right) + 1;
	}
	bool _isbalance(Node* root)
	{
		if (root == nullptr) return true;
		int left = _height(root->_left);
		int right = _height(root->_right);

		if (abs(left - right) >= 2) return false;
		if (right - left != root->_bf) return false;

		return _isbalance(root->_left)
			&& _isbalance(root->_right);
	}
private:
	Node* _root = nullptr;
};

Ⅱ. RBTree

前言:

  • 有AVLTree为什么还要有红黑树呢?因为AVLTree的要求太过苛刻,要求左右高度差不超过1,这就意味着插入的时候需要频繁旋转调整
  • 有人提出了红黑树(即相对不严格的平衡二叉树),即最长路径不超过最短路径二倍的树
  • 因为在logN的查找时间复杂度中,多加几层的查找无关紧要,结果仍然是查找的很快
  • 红黑树的要求:1. 根节点必须是黑色,2. 且不能存在连续的红色节点,3.每条路径上具有相同的黑色点个数,4.若此节点为红色,那么它的两个孩子必须为黑色
  • 为什么红黑树的这几点性质,就能保证其最长路径不超过最短路径二倍?因为最短无疑是全黑,最长无疑是在黑节点之间插入红(一黑一红,或两黑无红),其红不能连续,且红后必为黑,也有可能相邻黑之间无红,这就可以保证所有路径中最长路径不超过最短路径的二倍
// 节点定义
enum colour {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;

	colour _col;

	RBTreeNode(const pair<K,V> & kv)
		:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_col(RED)
	{}
};

因为插入节点默认为红色,如果为黑色,就改变了所有路径黑色节点个数一样的性质,此性质难以把握,故插入红色,而插入红色时,若父亲为黑,无需理会直接插入,若插入节点的父亲是红色,则不满足无连续红节点的性质,所以需要向上调整颜色

1. 插入后只变色

父亲的兄弟为红时
在这里插入图片描述
将parent变黑,grandfather变红,迭代向上变

2. 插入后旋转加变色

父亲无兄弟,或有兄弟且为黑时
在这里插入图片描述
仅仅将parent变黑已经 不满足所有路径黑色节点数量一致的性质,但此时如果将grandfather进行有单旋外加变色就可以保持平衡

3. 底层实现

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->_col = BLACK;
			return true;
		}

		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kv.first < cur->_kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (kv.first > cur->_kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(kv);
		if (kv.first < parent->_kv.first)
			parent->_left = cur;
		else
			parent->_right = cur;
		cur->_parent = parent;

		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;

			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

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

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

					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
		}

		_root->_col = BLACK;
		return true;
	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

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

		subL->_right = parent;

		Node* ppNode = parent->_parent;
		parent->_parent = subL;

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

			subL->_parent = ppNode;
		}
	}

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

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

		subR->_left = parent;
		Node* ppNode = parent->_parent;

		parent->_parent = subR;

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

	void Inorder()
	{
		_Inorder(_root);
		cout << endl;
	}
	bool IsBalance()
	{
		// 规则一
		if (_root->_col != BLACK)
		{
			return false;
		}

		int blacksum = 0;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_col == BLACK) blacksum++;
			cur = cur->_left;
		}

		return check(_root, 0, blacksum);
	}
private:
	bool check(Node* root, int path, int blacksum)
	{
		if (root == nullptr)
		{
			// 规则四
			if (path != blacksum)
			{
				return false;
			}

			return true;
		}

		// 规则三
		if (root->_col == RED && root->_parent->_col == RED)
			return false;

		if (root->_col == BLACK) path++;

		return check(root->_left, path, blacksum)
			&& check(root->_right, path, blacksum);
	}

	void _Inorder(Node* root)
	{
		if (root == nullptr) return;
		_Inorder(root->_left);
		cout << root->_kv.first << " " << root->_kv.second << endl;
		_Inorder(root->_right);
	}

private:
	Node* _root = nullptr;
};

Ⅲ. map set的封装

1. map

	template<class K,class V>
	class map
	{
		struct MapKeyofT
		{
			const K& operator()(const pair<const K,V>& kv)
			{
				return kv.first;
			}
		};
	public:
		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<const K, V>& kv)
		{
			return _t.Insert(kv);
		}

		iterator find(const K& k)
		{
			return _t.Find(k);
		}

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

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

2. set

	template<class K>
	class set
	{
		struct SetKeyofT
		{
			const K& operator()(const K& k)
			{
				return k;
			}
		};
	public:
		typedef typename RBTree<K,const K, SetKeyofT>::Iterator iterator;
		typedef typename RBTree<K,const K, SetKeyofT>::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 K& k)
		{
			return _t.Insert(k);
		}

		iterator find(const K& k)
		{
			return _t.Find(k);
		}

	private:
		RBTree<K,const K, SetKeyofT> _t;
	};

3.完善RBTree

#pragma once

enum colour {RED,BLACK};

template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	T _data;

	colour _col;

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

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

	Node* _node;

	__RBTree_Iterator(Node* node)
		:_node(node)
	{}

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

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

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

	Self& operator++()
	{
		if (_node->_right)
		{
			Node* leftMin = _node->_right;
			while (leftMin->_left)
				leftMin = leftMin->_left;

			_node = leftMin;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = cur->_parent;
			}

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


template<class K, class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef __RBTree_Iterator<T, T&, T*> Iterator;
	typedef __RBTree_Iterator<T,const T&,const T*> Const_Iterator;
	
	Iterator Begin()
	{
		Node* leftMin = _root;
		while (leftMin && leftMin->_left)
			leftMin = leftMin->_left;

		return Iterator(leftMin);
	}

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

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

		return Iterator(leftMin);
	}

	Const_Iterator End() const
	{
		return Iterator(nullptr);
	}

	RBTree() = default;

	RBTree(const RBTree<K, T, KeyOfT>& t)
	{
		_root = copy(t._root);
	}

	RBTree<K, T, KeyOfT>& operator=(RBTree<K, T, KeyOfT> t)
	{
		std::swap(_root, t._root);
		return *this;
	}

	~RBTree()
	{
		destroy(_root);
		_root = nullptr;
	}

	pair<Iterator,bool> Insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return make_pair(Iterator(_root), false);
		}

		KeyOfT kot;
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kot(data) < kot(cur->_data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (kot(data) > kot(cur->_data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return make_pair(Iterator(cur), true);
			}
		}
		
		cur = new Node(data);
		Node* newnode = cur;
		if (kot(data) < kot(parent->_data))
			parent->_left = cur;
		else
			parent->_right = cur;
		cur->_parent = parent;

		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

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

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

					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
		}

		_root->_col = BLACK;
		return make_pair(Iterator(newnode), false);
	}

	Iterator Find(const K& k)
	{
		KeyOfT kot;
		Node* cur = _root;
		while (cur)
		{
			if (k < kot(cur->_data))
			{
				cur = cur->_left;
			}
			else if(k > kot(cur->_data))
			{
				cur = cur->_right;
			}
			else
			{
				return Iterator(cur);
			}
		}
		return Iterator(nullptr);
	}
	
	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

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

		subL->_right = parent;

		Node* ppNode = parent->_parent;
		parent->_parent = subL;

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

			subL->_parent = ppNode;
		}
	}

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

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

		subR->_left = parent;
		Node* ppNode = parent->_parent;

		parent->_parent = subR;

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

	bool IsBalance()
	{
		if (_root == nullptr) return true;
		
		if (_root->_col != BLACK)
			return false;
		
		int blacksum = 0;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_col == BLACK) blacksum++;
			cur = cur->_left;
		}

		return check(_root, 0, blacksum);
	}

private:
	bool check(Node* root, int path, int blacksum)
	{
		if (root == nullptr)
		{
			if (path != blacksum)
				return false;

			return true;
		}
		
		if (root->_col == RED && root->_parent->_col == RED)
			return false;

		if (root->_col == BLACK)
			path++;

		return check(root->_left, path, blacksum)
			&& check(root->_right, path, blacksum);
	}

	void destroy(Node* root)
	{
		if (root == nullptr)
			return;
		
		destroy(root->_left);
		destroy(root->_right);
		delete root;
		root = nullptr;
	}
	
	Node* copy(Node* root)
	{
		if (root == nullptr)
			return nullptr;

		Node* newnode = new Node(root->_data);
		newnode->_col = root->_col;

		newnode->_left = copy(root->_left);
		if (newnode->_left)
			newnode->_left->_parent = newnode;

		newnode->_right = copy(root->right);
		if (newnode->_right)
			newnode->_right->_parent = newnode;
		
		return newnode;
	}
private:
	Node* _root = nullptr;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值