为了保持AVL树的平衡性,插入和删除操作后,非常频繁地调整全树整体拓扑结构,代价较大。
为此在AVL树的平衡标准上进一步放宽条件,引入红黑树的结构。
一颗红黑树是满足如下红黑性质的二叉排序树:
- 每个结点或是红色,或是黑色的。
- 根结点是黑色的。
- 叶结点(虚构的外部节点、null节点)都是黑色的。
- 不存在两个相邻的红结点(即红节点的父结点和孩子结点均是黑色的)。
- 对每个结点,从该结点到任一叶节点的简单路径上,所含黑结点的数量相同。
红黑树的“适度平衡”,由AVL树的“高度平衡”,降低到“任意节点左右子树的高度,相差不超过2倍”,也降低了动态操作时调整的频率。对于一颗动态查找树,如果插入和删除操作比较少,查找操作比较多,采用AVL树比较合适,否则采用红黑树更合适。
常规红黑树为2-3-4-B树的推广,左倾红黑树为2-3-B树的推广,详情见《算法(第四版)》书中2-3树与红黑树一栏。
C++代码:
#include
#include
#include
static const bool RED = true;
static const bool BLACK = false;
template <typename Key, typename Value>
class Node
{
public:
Key key;
Value val;
Node *left, *right;
int N; // 该棵子树中的结点占总数
bool color;
Node(Key key, Value val, int N, bool color) : left(0), right(0)
{
this->key = key;
this->val = val;
this->N = N;
this->color = color;
}
};
template <typename Key, typename Value>
class RedBlackBTS
{
friend class Node<Key, Value>;
public:
RedBlackBTS() : root(0) {}
void put(Key key, Value val)
{
this->root = put(this->root, key, val);
this->root->color = BLACK;
}
Node<Key, Value> *put(Node<Key, Value> *h, Key key, Value val)
{
if (h == NULL)
{
Node<Key, Value> *t = new Node<Key, Value>(key, val, 1, RED);
return t;
}
if (key < h->key)
{
h->left = put(h->left, key, val);
}
else if (key > h->key)
{
h->right = put(h->right, key, val);
}
else
{
h->val = val;
}
// 将任意含有红色右链接的3-结点(或临时的4-结点)向左旋转。
if (isRed(h->right) && !isRed(h->left))
h = rotateLeft(h);
// 将临时的4-结点中两条连续红链接中的上层链接向右旋转。
if (isRed(h->left) && isRed(h->left->left))
h = rotateRight(h);
// 颜色转换并将红链接向上传递。
if (isRed(h->left) && isRed(h->right))
flipColors(h);
h->N = TreeSize(h->left) + TreeSize(h->right) + 1;
return h;
}
Node<Key, Value> *balance(Node<Key, Value> *h)
{
// 没看懂这行代码什么意思?!
if (isRed(h->right))
h = rotateLeft(h);
// 经过第一步旋转,h->left必为红啊
// 将任意含有红色右链接的3-结点(或临时的4-结点)向左旋转。
if (isRed(h->right) && !isRed(h->left))
{
h = rotateLeft(h);
}
// 将临时的4-结点中两条连续红链接中的上层链接向右旋转。
if (isRed(h->left) && isRed(h->left->left))
h = rotateRight(h);
// 颜色转换并将红链接向上传递。
if (isRed(h->left) && isRed(h->right))
flipColors(h);
h->N = TreeSize(h->left) + TreeSize(h->right) + 1;
return h;
}
void leval_traversal()
{
leval_traversal(root);
}
void leval_traversal(Node<Key, Value> *h)
{
std::cout << "leval_traversal: " << std::endl;
std::queue<std::pair<Node<Key, Value> *, int>> q;
q.push(std::make_pair(h, 0));
int cnt = 0;
while (!q.empty())
{
std::pair<Node<Key, Value> *, int> p = q.front();
q.pop();
if (p.second != cnt)
{
++cnt;
std::cout << '\n';
}
if ((Node<Key, Value> *)p.first == NULL)
std::cout << "# ";
else
{
std::cout << p.first->key << '/' << p.first->color << ' ';
q.push(std::make_pair(p.first->left, cnt + 1));
q.push(std::make_pair(p.first->right, cnt + 1));
}
}
std::cout << std::endl;
}
Node<Key, Value> *deleteMin(Node<Key, Value> *h);
void deleteMin();
Node<Key, Value> *moveRedLeft(Node<Key, Value> *h);
Node<Key, Value> *deleteMax(Node<Key, Value> *h);
void deleteMax();
Node<Key, Value> *moveRedRight(Node<Key, Value> *h);
Node<Key, Value> *deleteKey(Node<Key, Value> *h, Key key);
void deleteKey(Key key);
Node<Key, Value> *MinNode(Node<Key, Value> *h)
{
return h->left == NULL ? h : MinNode(h->left);
}
private:
bool isRed(Node<Key, Value> *x)
{
if (x == NULL)
return false; // 我们约定空连接为黑色
return x->color == RED;
}
int TreeSize(Node<Key, Value> *h)
{
if (h == NULL)
return 0;
else
return h->N;
}
Node<Key, Value> *root;
Node<Key, Value> *rotateLeft(Node<Key, Value> *h);
Node<Key, Value> *rotateRight(Node<Key, Value> *h);
void flipColors(Node<Key, Value> *h);
void flipColors_delete(Node<Key, Value> *h)
{
h->color = BLACK;
h->left->color = RED;
h->right->color = RED;
}
};
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::rotateLeft(Node<Key, Value> *h)
{
if (h->right == NULL)
return h;
Node<Key, Value> *x = h->right;
h->right = x->left;
x->left = h;
x->color = h->color;
h->color = RED;
x->N = h->N;
h->N = TreeSize(h->left) + TreeSize(h->right) + 1;
return x;
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::rotateRight(Node<Key, Value> *h)
{
if (h->left == NULL)
return h;
Node<Key, Value> *x = h->left;
h->left = x->right;
x->right = h;
x->color = h->color;
h->color = RED;
x->N = h->N;
h->N = TreeSize(h->left) + TreeSize(h->right) + 1;
return x;
}
template <typename Key, typename Value>
void RedBlackBTS<Key, Value>::flipColors(Node<Key, Value> *h)
{
h->color = RED;
h->left->color = BLACK;
h->right->color = BLACK;
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::moveRedLeft(Node<Key, Value> *h)
{
// 假设结点h为红结点且h->left与h->left->left均为黑色。
// 将h->left或h->left的紫结点之一变红。
flipColors_delete(h);
if (isRed(h->right->left))
{
h->right = rotateRight(h->right);
h = rotateLeft(h);
}
return h;
}
template <typename Key, typename Value>
void RedBlackBTS<Key, Value>::deleteMin()
{
// 确保根结点为3-结点
if (!isRed(root->left) && !isRed(root->right))
{
root->color = RED;
}
root = deleteMin(root);
if (root != NULL)
root->color = BLACK;
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::deleteMin(Node<Key, Value> *h)
{
// std::cout << "moveRedLeft: ";
// leval_traversal(h);
// 删除操作
if (h->left == NULL)
{
free(h);
return NULL;
}
// 将3-结点与4-结点下移
if (!isRed(h->left) && !isRed(h->left->left))
{
h = moveRedLeft(h);
}
h->left = deleteMin(h->left);
return balance(h);
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::moveRedRight(Node<Key, Value> *h)
{
// 假设结点h为红结点且h->left与h->right->left均为黑色。
// 将h->left或h->left的子结点之一变红。
flipColors_delete(h);
if (!isRed(h->left->left))
{
h = rotateRight(h);
}
return h;
}
template <typename Key, typename Value>
void RedBlackBTS<Key, Value>::deleteMax()
{
// 确保根结点为3-结点
if (!isRed(root->left) && !isRed(root->right))
{
root->color = RED;
}
root = deleteMax(root);
if (root != NULL)
root->color = BLACK;
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::deleteMax(Node<Key, Value> *h)
{
// 将左倾红黑树在h结点规范为右倾
if (isRed(h->left))
h = rotateRight(h);
if (h->right == NULL)
{
free(h);
return NULL;
}
// 将3-结点与4-结点下移
if (!isRed(h->right) && !isRed(h->right->left))
{
h = moveRedRight(h);
}
h->right = deleteMax(h->right);
return balance(h);
}
template <typename Key, typename Value>
void RedBlackBTS<Key, Value>::deleteKey(Key key)
{
if (!isRed(root->left) && !isRed(root->right))
{
root->color = RED;
}
root = deleteKey(root, key);
if (root != NULL)
root->color = BLACK;
}
template <typename Key, typename Value>
Node<Key, Value> *RedBlackBTS<Key, Value>::deleteKey(Node<Key, Value> *h, Key key)
{
if (key < root->key)
{
if (!isRed(h->left) && !isRed(h->left->left))
{
h = moveRedLeft(h);
}
h->left = deleteKey(h->left, key);
}
else
{
if (isRed(h->left))
{
h = rotateRight(h);
}
// 在叶子结点,没有右结点,根据第一行代码可知,当前必没有左节点,因此可以直接进行删除操作。
if(key == h->key && h->right == NULL) {
return NULL;
}
if (!isRed(h->right) && !isRed(h->right->left))
{
h = moveRedRight(h);
}
if(key == h->key) {
Node<Key, Value>* t = MinNode(h->right);
h->val = t->val;
h->key = t->key;
h->right = deleteMin(h->right);
}
else h->right = deleteKey(h->right, key);
}
return balance(h);
}
int main()
{
RedBlackBTS<int, int> rbt;
for (int i = 7; i > 0; --i)
{
rbt.put(i, 1);
}
rbt.leval_traversal();
rbt.deleteMin();
rbt.leval_traversal();
rbt.deleteMax();
rbt.leval_traversal();
rbt.deleteKey(4);
rbt.leval_traversal();
}