AVL树/红黑树介绍及插入操作实现

一.AVL树概念

二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。

一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:
它的左右子树都是AVL树
左右子树高度之差(简称平衡因子)的绝对值不超过1( 可以为-1/0/1 )

在这里插入图片描述

二.AVL树模拟实现

AVL树接口总览

template<class K,class V>
struct AVLTreeNode
{
	AVLTreeNode(const pair<K,V>& kv)
		:_left(nullptr)
		,_right(nullptr)
		,_parent(nullptr)
		,_bf(0)
		,_kv(kv)
	{}
	AVLTreeNode* _left; // 指向左子树节点
	AVLTreeNode* _right; // 指向右子树节点
	AVLTreeNode* _parent; // 指向父节点
	int _bf;  // 平衡因子
	pair<K, V> _kv; // 节点数据
};
template<class K,class V>
class AVLTree
{
	typedef AVLTreeNode<K, V> Node;
public:
	AVLTree()
		:_root(nullptr)
	{}
	~AVLTree();
	Node* Find(const K& key);
	V& operator[](const K& key);
	bool IsAVLTree();
	void InOrder();
	bool Insert(const pair<K, V>& kv);
	void RotateL(Node* parent);
	void RotateR(Node* parent);
	void RotateLR(Node* parent);
	void RotataRL(Node* parent);
private:
	Node* _root;
};

当插入一个新节点的时候,首先根据二叉搜索树的性质,比根节点小的去左子树查找,比根节点大的去右子树查找,循环找到新节点的位置,如果是二叉搜索树的话,插入操作到此就完成了,但AVL树需要保证平衡因子的绝对值不超过1,所以我们还需要更新 新节点沿着父节点的路径上的平衡因子,如果有绝对值超过2的平衡因子,则需要进行旋转操作

在这里插入图片描述

右单旋 :

在这里插入图片描述

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

	parent->_left = subLR;
	subL->_right = parent;
	if (subLR)
		subLR->_parent = parent;
	if (parent == _root)
	{
		_root = subL;
		_root->_parent = nullptr;
	}
	else
	{
		if (parentParent->_right == parent) parentParent->_right = subL;
		else parentParent->_left = subL;
		subL->_parent = parentParent;
	}
	parent->_parent = subL;
	subL->_bf = parent->_bf = 0;
}

左单旋 :

在这里插入图片描述

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

	parent->_right = subRL;
	subR->_left = parent;
	if (subRL)
		subRL->_parent = parent;
	if (parent == _root)
	{
		_root = subR;
		_root->_parent = nullptr;
	}
	else
	{
		if (parentParent->_right == parent) parentParent->_right = subR;
		else parentParent->_left = subR;
		subR->_parent = parentParent;
	}
	parent->_parent = subR;
	subR->_bf = parent->_bf = 0;
}

左右双旋 :

在这里插入图片描述

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

右左双旋 :

在这里插入图片描述

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

插入操作

pair<Node*, bool> Insert(const pair<K, V>& kv)
{
	// 完成插入操作
	if (_root == nullptr)
	{
		_root = new Node(kv);
		return pair<Node*,bool>(_root,true);
	}
	Node* parent = _root, * 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 pair<Node*,bool>(cur, false);
		}
	}
	cur = new Node(kv);
	if (parent->_kv.first < cur->_kv.first) parent->_right = cur;
	else parent->_left = cur;
	cur->_parent = parent;
	Node* tmp = cur;
	// 更新平衡因子
	while (cur != _root)
	{
		if (parent->_kv.first < cur->_kv.first) ++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)
			{
				// 右单旋
				if (cur->_bf == -1) RotateR(parent);
				// 左右双旋
				else if (cur->_bf == 1) RotateLR(parent);
			}
			else if (parent->_bf == 2)
			{
				// 左单旋
				if (cur->_bf == 1) RotateL(parent);
				// 右左双旋
				else if (cur->_bf == -1) RotateRL(parent);
			}
			break;
		}
	}
	return pair<Node*,bool>(tmp, true);
}

查找操作,根据key值进行查找即可

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

operator[]
如果AVL树中已经存在相同的key值,返回与之相同的key值的val,若不存在,则新插入一个节点,返回该节点的val值

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

检验AVL树是否平衡
(1). 检验右子树高度 - 左子树高度是否等于平衡因子(bf)
(2). 检验右子树高度 - 左子树高度的绝对值是否小于2

// 求子树高度
int _Height(Node* root)
{
	if (root == nullptr) return 0;
	int LeftHeight = _Height(root->_left);
	int RightHeight = _Height(root->_right);
	// 左右子树中更高的树的高度 + 1
	return LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;
}
bool _IsBalance(Node* root)
{
	if (root == nullptr) return true;

	int LeftHeight = _Height(root->_left);
	int RightHeight = _Height(root->_right);
	// 检验右子树高度 - 左子树高度是否等于平衡因子(bf)
	if (RightHeight - LeftHeight != root->_bf)
	{
		cout << "平衡因子异常 : " << root->_kv.first << endl;
		return false;
	}
	// 检验右子树高度 - 左子树高度的绝对值是否小于2并去递归检测左右子树
	return abs(RightHeight - LeftHeight) < 2 && _IsBalance(root->_left) && _IsBalance(root->_right);
}
bool IsAVLTree()
{
	return _IsBalance(_root);
}

AVLTree代码实现

三.红黑树概念

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍(最长路径不能超过最短路径的2倍),因而是接近平衡的。

(1). 每个结点不是红色就是黑色
(2). 根节点是黑色的
(3). 如果一个节点是红色的,则它的两个孩子结点是黑色的 (没有连续的红色节点)
(4). 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点 (每条路径上都包含相同数量的黑色节点)
(5). 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
满足以上性质,最短路径为全为黑色节点的路径,最长路径为一黑一红节点交替的路径,保证了最长路径为最短路径的2倍

四.红黑树模拟实现

红黑树接口总览

enum Colour
{
	RED,
	BLACK,
};
template<class K, class V>
struct RBTreeNode
{
	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		,_col(RED)
		, _kv(kv)
	{}
	RBTreeNode<K, V>* _left;
	RBTreeNode<K, V>* _right;
	RBTreeNode<K, V>* _parent;
	pair<K, V> _kv;
	Colour _col;
};
template<class K, class V>
class RBTree
{
	typedef RBTreeNode<K, V> Node;
public:
	pair<Node*, bool> Insert(const pair<K, V>& kv);
	bool IsBalance();
private:
	Node* _root;
}

插入操作 :

首先我们默认插入的节点是红色的,这是因为如果插入黑色节点的话,会影响某条路径上的黑色节点数量,而红黑树要求每条路径上的黑色节点数量一致,所以插入黑色节点操控起来难度更大

(1). 按照二叉搜索树的规则找到节点应该插入的位置
(2). 如果插入节点的父亲是黑色节点,并没有违反红黑树的规定,不用进行操作
(3). 如果插入节点的父亲是红色节点,说明祖父节点一定是黑色节点(如果祖父不是黑色节点,那在插入之前就已经不是红黑树了,因为祖父节点和父亲节点都是红色节点),所以此时就需要看叔叔节点了,叔叔节点分为以下3种情况

一. uncle节点存在且为红

将parent节点和uncle节点变为黑色节点,grandfather节点变为红色节点,然后循环 cur = grandparent,parent = cur->parent,直到parent为空

在这里插入图片描述

二. uncle节点不存在/存在且为黑(单旋转 + 变色)

uncle不存在
在这里插入图片描述

uncle存在,以grandfather为根进行右单旋,parent变为黑,grandfather变为红

在这里插入图片描述

uncle存在,以grandfather为根进行左单旋,parent变为黑,grandfather变为红
在这里插入图片描述

三. uncle节点不存在/存在且为黑(双旋转 + 变色)

uncle不存在,以parent为旋转点,进行左单旋,以grandfather为旋转点进行右单旋
在这里插入图片描述

uncle存在,以parent为旋转点,进行左单旋,以grandfather为旋转点进行右单旋

在这里插入图片描述

插入操作实现

pair<Node*, bool> Insert(const pair<K, V>& kv)
{
	// 插入第一个节点
	if (_root == nullptr)
	{
		_root = new Node(kv);
		_root->_col = BLACK;
		return make_pair(_root, true);
	}
	// 找到对应的位置进行插入
	Node* parent = _root, * 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 make_pair(cur, false);
		}
	}
	cur = new Node(kv);
	if (parent->_kv.first < cur->_kv.first) parent->_right = cur;
	else parent->_left = cur;
	cur->_parent = parent;
	// parent是红色节点的几种情况
	while (parent && parent->_col == RED)
	{
		Node* grandfather = parent->_parent;
		if (parent == grandfather->_left)
		{
			Node* uncle = grandfather->_right;
			// 情况1 : uncle存在且为red
			if (uncle && uncle->_col == RED)
			{
				parent->_col = uncle->_col = BLACK;
				grandfather->_col = RED;

				cur = grandfather;
				parent = cur->_parent;
			}
			// 情况2 + 3 : uncle不存在/uncle存在且为黑
			else
			{
				if (cur == parent->_left)
				{
					RotateR(grandfather);
					grandfather->_col = RED;
					parent->_col = BLACK;
				}
				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(cur, true);
}

检测红黑树
(1). 根节点不能是红色
(1). 不能有连续的红色节点
(2). 每条路径上黑色节点数量一样

bool _IsBalance(Node* root, int blacknum, int count)
{
	if (root == nullptr)
	{
		if (count != blacknum) return false;
		return true;
	}
	// 不能有连续的红色节点
	if (root->_col == RED && root->_parent->_col == RED) return false;
	// 记录黑色节点的数量
	if (root->_col == BLACK) count++;

	return _IsBalance(root->_left, blacknum, count)
		&& _IsBalance(root->_right, blacknum, count);
}
bool IsBalance()
{
	// 根节点不能是红色
	if (_root->_col == RED) return false;
	// blacknum 记录黑色节点数量
	int blacknum = 1;
	Node* left = _root->_left;
	while (left)
	{
		if (left->_col == BLACK) blacknum++;
		left = left->_left;
	}
	int count = 0;
	// 检测
	return _IsBalance(_root, blacknum, count);
}

红黑树代码实现

五. map/set模拟实现

在这里插入图片描述

我们先看STL中map/set容器的实现思路,map/set底层都是用红黑树来实现的

typedef Key key_type;
typedef pair<const Key,T> value_type;
typedef rb_tree<key_type,value_type,select1st<value_type>,key_compare,Alloc> rep_type;

map中key_type是key,value_type是pair<const K,T>,
在rb_tree中使用value_type实例化出 _rb_tree_node
select1st<value_type>作为仿函数传给rb_tree的class KeyOfValue,用来获取value_type中的key值

set中key_type是key,value_type也是key,
在rb_tree中使用value_type实例化出 _rb_tree_node
identity<value_type>作为仿函数传给rb_tree的class KeyOfValue,用来获取value_type中的key值

RBTree 改造

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

template<class K, class T>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	pair<Node*, bool> Insert(const pair<T>& kv);
	bool IsBalance();
private:
	Node* _root;
}

Map接口总览

namespace lyp
{
	template<class K, class V>
	class map
	{
		// 获取pair结构体中的key值
		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>::reverse_iterator reverse_iterator;
		reverse_iterator rbegin()
		{
			return _t.rbegin();
		}
		reverse_iterator rend()
		{
			return _t.rend();
		}
		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		pair<iterator,bool> insert(const pair<const 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;
	};
}

RBTree中正向迭代器的实现

template<class T,class Ref,class Ptr>
struct _TreeIterator
{
	typedef Ref reference;
	typedef Ptr pointer;
	typedef RBTreeNode<T> Node;
	// Self自身类型
	typedef _TreeIterator<T, Ref, Ptr> Self;
	_TreeIterator(Node* node)
		:_node(node)
	{}
	// 返回节点数据的引用
	Ref operator*()
	{
		return _node->_data;
	}
	// 返回节点数据的指针
	Ptr operator->()
	{
		return &_node->_data;
	}
	// 判断节点指针是否一致
	bool operator!=(const Self& s)const
	{
		return _node != s._node;
	}
	// 后置++
	Self& operator++(int)
	{
		// 右树不为空,找到右树的最左节点
		if (_node->_right)
		{
			Node* left = _node->_right;
			while (left->_left) left = left->_left;
			_node = left;
		}
		// 右树为空,找到第一个左节点等于cur的节点
		else
		{
			Node* cur = _node, * parent = cur->_parent;
			while (parent && parent->_right == cur)
			{
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	Self& operator--()
	{
		// 左树不为空,找到左树的最右节点
		if (_node->_left)
		{
			Node* right = _node->_left;
			while (right->_right) right = right->_right;
			_node = right;
		}
		// 左树为空,找到第一个右节点等于cur的节点
		else
		{
			Node* cur = _node, * parent = cur->_parent;
			while (parent && parent->_left == cur)
			{
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	Node* _node;
};

RBTree中反向迭代器的实现 : 反向迭代器是由正向迭代器封装出来的

template<class Iterator>
struct ReverseIterator
{
	typedef typename Iterator::reference Ref;
	typedef typename Iterator::pointer Ptr;
	typedef ReverseIterator<Iterator> Self;
	ReverseIterator(Iterator it)
		:_it(it)
	{}
	Ref operator*()
	{
		return *_it;
	}
	Ptr operator->()
	{
		return _it.operator->();
	}
	Self& operator++()
	{
		--_it;
		return *this;
	}
	Self& operator--()
	{
		_it++;
		return *this;
	}
	bool operator!=(const Self& s)const
	{
		return _it != s._it;
	}
	Iterator _it;
};

Map模拟实现
Set模拟实现

set.hpp

#pragma once

#include"RBTree.hpp"

namespace lyp
{
	template<class K>
	class set
	{
		struct KeyOfT
		{
			const K& operator()(const K& k)
			{
				return k;
			}
		};
	public:
		typedef typename RBTree<K, K, KeyOfT>::iterator iterator;
		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		bool insert(const K& k)
		{
			_t.Insert(k);

			return true;
		}
	private:
		RBTree<K,K,KeyOfT> _t;
	};
}

map.hpp

#pragma once
#include"RBTree.hpp"

namespace lyp
{
	template<class K, class V>
	class map
	{
		// 获取pair结构体中的key值
		struct KeyOfT
		{
			const K& operator()(const pair<const K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		typedef typename RBTree<K, pair<const K, V>, KeyOfT>::iterator iterator;
		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		bool insert(const pair<const K, V>& kv)
		{
			_t.Insert(kv);

			return true;
		}
		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>,KeyOfT> _t;
	};
}

RBTree.hpp

#pragma once
#include<iostream>
using namespace std;

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

template<class T,class Ref,class Ptr>
struct TreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef TreeIterator<T, Ref, Ptr> Self;
	Node* _node;

	TreeIterator(Node* node)
		:_node(node)
	{}
	
	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;
	}

	Self& operator++()
	{
		if(_node->_right)
		{
			Node* left = _node->_right;
			while (left->_left) left = left->_left;
			
			_node = left;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}

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

template<class K, class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef TreeIterator<T, T&, T*> iterator;
	RBTree()
		:_root(nullptr)
	{}
	~RBTree()
	{
		Destroy(_root);
		_root = nullptr;
	}
	iterator begin()
	{
		Node* left = _root;
		while (left && left->_left) left = left->_left;
		return iterator(left);
	}
	iterator end()
	{
		return iterator(nullptr);
	}
	void Destroy(Node* root)
	{
		if (!root) return;
		Destroy(root->_left);
		Destroy(root->_right);
		delete root;
	}
	Node* Find(const K& key)
	{
		KeyOfT kot;
		Node* cur = _root;
		while (cur)
		{
			if (kot(cur->_data) < key)
			{
				cur = cur->_right;
			}
			else if (kot(cur->_data) > key)
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}
		return nullptr;
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		Node* parentParent = parent->_parent;

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

		parent->_left = subLR;
		subL->_right = parent;
		if (subLR)
			subLR->_parent = parent;
		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (parentParent->_right == parent) parentParent->_right = subL;
			else parentParent->_left = subL;
			subL->_parent = parentParent;
		}
		parent->_parent = subL;
	}
	void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

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

		RotateR(subR);
		RotateL(parent);
	}
	pair<iterator, bool> Insert(const T& data)
	{
		KeyOfT kot;
		// 插入第一个节点
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return make_pair(_root, true);
		}
		// 找到对应的位置进行插入
		Node* parent = _root, * 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), false);
			}
		}
		cur = new Node(data);
		if (kot(parent->_data) < kot(cur->_data)) parent->_right = cur;
		else parent->_left = cur;
		cur->_parent = parent;
		// parent是红色节点的几种情况
		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;
				// 情况1 : uncle存在且为red
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				// 情况2 + 3 : uncle不存在/uncle存在且为黑
				else
				{
					if (cur == parent->_left)
					{
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					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(cur), true);
	}
	bool _IsBalance(Node* root, int blacknum, int count)
	{
		if (root == nullptr)
		{
			if (count != blacknum) return false;
			return true;
		}
		// 不能有连续的红色节点
		if (root->_col == RED && root->_parent->_col == RED) return false;
		// 记录黑色节点的数量
		if (root->_col == BLACK) count++;

		return _IsBalance(root->_left, blacknum, count)
			&& _IsBalance(root->_right, blacknum, count);
	}
	bool IsBalance()
	{
		// 根节点不能是红色
		if (_root->_col == RED) return false;
		// blacknum 记录黑色节点数量
		int blacknum = 1;
		Node* left = _root->_left;
		while (left)
		{
			if (left->_col == BLACK) blacknum++;
			left = left->_left;
		}
		int count = 0;
		// 检测
		return _IsBalance(_root, blacknum, count);
	}
private:
	Node* _root;
};




  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值