红黑树前言: 单从红黑树的基本实现来说,是比AVLTree的实现更简单,但要用一棵红黑树(一份红黑树代码)来实现map/set及其相应的迭代器是有难度的
目录
-
红黑树的概念
-
红黑树的性质
-
红黑树的节点定义
-
红黑树的实现
- 红黑树的插入
- 第一步的过程
- 第二步的过程
- 红黑树的旋转
- 二叉树的查找
- 红黑树的插入
-
红黑树的迭代器
-
map/set封装实现
-
完整版参考代码
红黑树的概念
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
红黑树的性质
- 每个结点不是红色就是黑色
- 根节点是黑色的
- 如果一个节点是红色的,则它的两个孩子结点是黑色的
- 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
红黑树的定义
红黑树的实现
因为红黑树为二叉搜索树,所以红黑树遵守二叉搜索树的规则
红黑树的插入
红黑树就是在二叉搜索树的基础上引入颜色,因此AVL树也可以看成是二叉搜索树。那么
红黑树的插入过程可以分为两步:
- 按照二叉搜索树的方式插入新节点
- 调整节点颜色(旋转+变色)
第一步的过程:
按照二叉搜索树的方式插入新节点
第二步的过程:
调整结点颜色
红黑树的旋转
红黑树单旋的抽象图
情况一(只需要处理颜色):
p(parent)和u(uncle)都为红-------------------------------->调整:parent和uncle都变为黑,grandparent变为红(若grandparent为根,则将grandparent再变为黑)
情况一处理完后需要再往上处理(grandparent及其父亲若都为红的话)
情况二(需要旋转+处理颜色):
红黑树旋转演示:
红黑树的单旋(左单旋+右单旋+变色)
左单旋,右单旋参考代码:
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
Node* ppNode = parent->_parent;
parent->_right = subRL;
parent->_parent = subR;
subR->_left = parent;
subR->_parent = ppNode;
if (subRL)
{
subRL->_parent = parent;
}
if (_root == parent)
{
_root = subR;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
}
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
Node* ppNode = parent->_parent;
if (subLR)
subLR->_parent = parent;
parent->_left = subLR;
parent->_parent = subL;
subL->_right = parent;
subL->_parent = ppNode;
if (_root == parent)
{
_root = subL;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = subL;
else
ppNode->_right = subL;
}
}
红黑树的双旋:
红黑树处理颜色:
二叉树的查找
查找和插入第一步的逻辑差不多
红黑树的迭代器
有了迭代器,之前的接口返回值都需变化一下。参考最后的完整代码
map/set的封装实现
完整版参考代码
#include<iostream>
#include<string>
using namespace std;
enum Colour
{
BLACK,
RED,
};
template<class T>
struct RBTreeNode
{
RBTreeNode(const T& data)
:_data(data)
{}
RBTreeNode<T>* _left = nullptr;
RBTreeNode<T>* _right = nullptr;
RBTreeNode<T>* _parent = nullptr;
T _data;
Colour _col = RED;
};
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)
{}
T& operator*()
{
return _node->_data;
}
T* operator->()
{
return &(_node->_data);
}
Self operator++()
{
Node* cur = _node;
Node* parent = _node->_parent;
if (cur->_right)
{
cur = cur->_right;
while (cur && cur->_left)
{
cur = cur->_left;
}
_node = cur;
}
else
{
while (parent)
{
if (parent->_left == cur)
{
_node = parent;
break;
}
else
{
cur = parent;
parent = parent->_parent;
}
}
_node = parent;
}
return *this;
}
Self operator--()
{
//与++是反逻辑
return *this;
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
};
template<class K, class T, class KeyOfT>
class RBTree
{
typedef RBTreeNode<T> Node;
public:
typedef __TreeIterator<T, T*, T&> iterator;
typedef __TreeIterator<T, const T*, const T&> const_iterator;
iterator begin()
{
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
parent = cur;
cur = cur->_left;
}
return iterator(parent);
}
iterator end()
{
return iterator(nullptr);
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
Node* ppNode = parent->_parent;
parent->_right = subRL;
parent->_parent = subR;
subR->_left = parent;
subR->_parent = ppNode;
if (subRL)
{
subRL->_parent = parent;
}
if (_root == parent)
{
_root = subR;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
}
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
Node* ppNode = parent->_parent;
if (subLR)
subLR->_parent = parent;
parent->_left = subLR;
parent->_parent = subL;
subL->_right = parent;
subL->_parent = ppNode;
if (_root == parent)
{
_root = subL;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = subL;
else
ppNode->_right = subL;
}
}
pair<iterator, bool> Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(iterator(_root), true);
}
Node* cur = _root;
Node* parent = nullptr;
KeyOfT koft;
while (cur)
{
if (koft(cur->_data) > koft(data))
{
parent = cur;
cur = cur->_left;
}
else if (koft(cur->_data) < koft(data))
{
parent = cur;
cur = cur->_right;
}
else
{
return make_pair(iterator(cur), false);
}
}
cur = new Node(data);
if (koft(parent->_data) < koft(cur->_data))
{
cur->_parent = parent;
parent->_right = cur;
}
else
{
cur->_parent = parent;
parent->_left = cur;
}
if (parent->_col == BLACK)
{
return make_pair(iterator(cur), true);
}
Node* ret = cur;
while (parent && parent->_col == RED)
{
Node* grandparent = parent->_parent;
if (grandparent->_left == parent)
{
//情况一
Node* uncle = grandparent->_right;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandparent->_col = RED;
cur = grandparent;
parent = grandparent->_parent;
}
else
{
if (parent->_right == cur)
{
RotateL(parent);
swap(parent, cur);
}
RotateR(grandparent);
grandparent->_col = RED;
parent->_col = BLACK;
break;
}
}
else
{
Node* uncle = grandparent->_left;
if (uncle && uncle->_col == RED)
{
uncle->_col = parent->_col = BLACK;
grandparent->_col = RED;
cur = grandparent;
parent = cur->_parent;
}
else
{
if (parent->_left == cur)
{
RotateR(parent);
swap(parent, cur);
}
RotateL(grandparent);
grandparent->_col = RED;
parent->_col = BLACK;
break;
}
}
_root->_col = BLACK;
}
return make_pair(iterator(ret), true);
}
iterator Find(T& data)
{
Node* cur = _root;
if (KeyOfT(data) > KeyOfT(cur->_data))
{
cur = cur->_right;
}
else if (KeyOfT(data) < KeyOfT(cur->_data))
{
cur = cur->_left;
}
else
{
return iterator(cur);
}
return iterator(nullptr);
}
private:
Node* _root = nullptr;
};
template<class K, class V>
class map
{
public:
struct MapKeyOfT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
//typedef __TreeIterator<pair<K, V>> iterator;
typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::iterator iterator;
iterator begin()
{
return _rbt.begin();
}
iterator end()
{
return _rbt.end();
}
pair<iterator, bool> Insert(const pair<K, V>& kv)
{
return _rbt.Insert(kv);
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = Insert(make_pair(key, V()));
//return (*(ret.first)).second;
return ret.first->second;
}
private:
RBTree<K, pair<K, V>, MapKeyOfT> _rbt;
};
template<class K>
class set
{
public:
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
//typedef __TreeIterator<K> iterator;
typedef typename RBTree<K, K, SetKeyOfT>::iterator iterator;//调红黑树里的,红黑树又调了别人的
iterator begin()
{
return _rbt.begin();
}
iterator end()
{
return _rbt.end();
}
pair<iterator, bool> Insert(const K& key)
{
return _rbt.Insert(key);
}
private:
RBTree<K, K, SetKeyOfT>_rbt;
};
void test()
{
//map<int, int> m;
//m.Insert(pair<int, int>(4, 4));
//m.Insert(pair<int, int>(1, 1));
//m.Insert(pair<int, int>(3, 3));
//m.Insert(pair<int, int>(5, 5));
//m.Insert(pair<int, int>(2, 2));
//map<int, int>::iterator it = m.begin();
//while (it != m.end())
//{
// *(it) = make_pair(1, 1);
// cout << (*it).first << ":" << (*it).second << " ";
// ++it;
//}
//cout << endl;
//
string strs[] = { "西瓜", "苹果", "香蕉", "苹果", "猕猴桃", "西瓜", "西瓜", "西瓜", "西瓜", };
map<string, int> m;
for (auto e : strs)
{
m[e]++;
}
for (auto e : m)
{
cout << e.first << ":" << e.second << " ";
}
}