一.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);
}
三.红黑树概念
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是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;
};
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;
};