1.红黑树简介
红黑树(Red Black Tree) 是一种自平衡二叉查找树,红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。
2.代码实现
#ifndef RBT_H
#define RBT_H
#include <iostream>
using namespace std;
enum Color
{
RED,
BLACK
};
template<typename K, typename V>
struct Node
{
K key;
V val;
int N;
Color color;
Node<K, V>* left;
Node<K, V>* right;
Node()
{
this->left = NULL;
this->right = NULL;
}
Node(K key, V val)
{
this->key = key;
this->val = val;
this->N = 1;
this->color = RED;
this->left = NULL;
this->right = NULL;
}
};
template<typename K, typename V>
class RBT
{
public:
RBT();
~RBT();
V Getval(const K& key) const;
Node<K, V>* Insert(const K& key, const V& val);
void Del(int arr[], int index, const K& key);
bool contain(const K& key) const;
int size() const;
void clean();
K minKey() const;
K MaxKey() const;
K CountLevel() const;
void pretree() const;
void midtree() const;
void lasttree() const;
protected:
Node<K, V>* root;
Node<K, V>* Roleft(Node<K, V>* node);
Node<K, V>* Roright(Node<K, V>* node);
void filpNode(Node<K, V>* node);
void ReFilpNode(Node<K, V>* node);
Node<K, V>* fixNode(Node<K, V>* node);
Node<K, V>* Insert(Node<K, V>* node, const K& key, const V& val);
V Getval(Node<K, V>* node, const K& key) const;
bool contain(Node<K, V>* node, const K& key) const;
Node<K, V>* del(int arr[], int index, Node<K, V>* node, const K& key);
void clean(Node<K, V>* node);
int size(Node<K, V>* node) const;
K minKey(Node<K, V>* node) const;
K MaxKey(Node<K, V>* node) const;
K CountLevel(Node<K, V>* node) const;
bool isRed(Node<K, V>* node);
void pretree(Node<K, V>* node) const;
void midtree(Node<K, V>* node) const;
void lasttree(Node<K, V>* node) const;
};
//构造 析构函数
template<typename K, typename V>
RBT<K, V>::RBT()
{
this->root = NULL;
}
template<typename K, typename V>
RBT<K, V>::~RBT()
{
clean(this->root);
}
/********************************************************************
函数名称: isRed
函数参数: @node 节点指针
函数说明: 判断节点的颜色
返回值: 成功返回true 失败返回false
*********************************************************************/
template<typename K, typename V>
bool RBT<K, V>::isRed(Node<K, V>* node)
{
if (node == NULL || node->color == BLACK)
return false;
else
return true;
}
/********************************************************************
函数名称: Insert
函数说明: 放入键值对<key,value> 若存在则将原有的value替换成新的value
返回值: 无
*********************************************************************/
template<typename K, typename V>
Node<K,V>* RBT<K, V>::Insert(const K& key, const V& val)
{
return this->root = Insert(this->root, key, val);
}
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Insert(Node<K, V>* node, const K& key, const V& val)
{
if (node == NULL)
return new Node<K, V>(key, val);
if (key > node->key)
node->right = Insert(node->right, key, val);
else if (key < node->key)
node->left = Insert(node->left, key, val);
else
node->val = val;
if (isRed(node->right) && !isRed(node->left))
node = Roleft(node);
if (node->left != NULL && isRed(node->left) && isRed(node->left->left))
node = Roright(node);
if (isRed(node->left) && isRed(node->right))
filpNode(node);
node->N = size(node->left) + size(node->right) + 1;
return node;
}
/********************************************************************
函数名称: Getval
函数说明: 获取指定key的value
返回值: value
*********************************************************************/
template<typename K, typename V>
V RBT<K, V>::Getval(const K& key) const
{
return Getval(this->root, key);
}
template<typename K, typename V>
V RBT<K, V>::Getval(Node<K, V>* node, const K& key) const
{
if (node == NULL)
return NULL;
if (key > node->key)
return Getval(node->right, key);
else if (key < node->key)
return Getval(node->left, key);
else
return node->val;
}
/********************************************************************
函数名称: clean
函数说明: 清空表
返回值: 无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::clean()
{
clean(this->root);
this->root = NULL;
}
template<typename K, typename V>
void RBT<K, V>::clean(Node<K, V>* node)
{
if (node == NULL)
return;
clean(node->left);
clean(node->right);
delete node;
}
/********************************************************************
函数名称: size
函数说明: 无
返回值: 红黑树节点个数
*********************************************************************/
template<typename K, typename V>
int RBT<K, V>::size() const
{
return size(this->root);
}
template<typename K, typename V>
int RBT<K, V>::size(Node<K, V>* node) const
{
if (node == NULL)
return 0;
return size(node->right) + size(node->left) + 1;
}
/********************************************************************
函数名称: Del
函数说明: 删除某个key
返回值: 无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::Del(int arr[], int index, const K& key)
{
this->root = del(arr, index, this->root, key);
}
int Delete(int arr[],int n, int x)
{
int p = 0, q = 0; //用p和q两个变量
while (q<n) //由q控制,扫描所有的元素
{
if (arr[q] != x)
{
arr[p] = arr[q];
p++;
}
q++;
}
return p;
}
template<typename K, typename V>
Node<K, V>* RBT<K, V>::del(int arr[],int index,Node<K, V>* node, const K& key)
{
RBT<int, int>RBT1;
if (node == NULL)
return NULL;
Delete(arr, index, key);
for (int i = 0; i < index - 1; i++)
{
RBT1.Insert(arr[i], i);
}
swap(this->root, RBT1.root);
root->color = BLACK;
return this->root;
}
/********************************************************************
函数名称: prevtree/midtree/lasttree
函数说明: 遍历
*********************************************************************/
template<typename K, typename V> //前序遍历
void RBT<K, V>::pretree() const
{
pretree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::pretree(Node<K, V>* node) const
{
if (node != NULL)
{
cout << node->key << '\t';
if (node->color == BLACK)
{
cout << "黑色" << endl;
}
else
{
cout << "红色" << endl;
}
pretree(node->left);
pretree(node->right);
}
}
template<typename K, typename V> //中序遍历
void RBT<K, V>::midtree()const
{
midtree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::midtree(Node<K, V>* node) const
{
if (node != NULL)
{
midtree(node->left);
cout << node->key << '\t';
if (node->color == BLACK)
{
cout << "黑色" << endl;
}
else
{
cout << "红色" << endl;
}
midtree(node->right);
}
}
template<typename K, typename V> //后序遍历
void RBT<K, V>::lasttree()const
{
lasttree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::lasttree(Node<K,V>* node) const
{
if (node != NULL)
{
lasttree(node->left);
lasttree(node->right);
cout << node->key << '\t';
if (node->color == BLACK)
{
cout << "黑色" << endl;
}
else
{
cout << "红色" << endl;
}
}
}
/********************************************************************
函数名称: contain
函数说明: 是否包含key
返回值: 包含返回true 不包含返回false
*********************************************************************/
template<typename K, typename V>
bool RBT<K, V>::contain(const K& key) const
{
return contain(this->root, key);
}
template<typename K, typename V>
bool RBT<K, V>::contain(Node<K, V>* node, const K& key) const
{
if (node == NULL)
return false;
if (key > node->key)
Getval(node->right, key);
else if (key < node->key)
Getval(node->left, key);
else
return true;
}
/********************************************************************
函数名称: Roleft
函数参数: 需要旋转的节点指针
函数说明: 将右节点旋转到左边并设置为红色
返回值: 旋转后的树根指针
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Roleft(Node<K, V>* node)
{
Node<K, V>* right = node->right;
node->right = right->left;
right->left = node;
right->color = node->color;
node->color = RED;
node->N = size(node->left) + size(node->right) + 1;
right->N = size(right->left) + size(right->right) + 1;
return right;
}
/********************************************************************
函数名称: Roright
函数参数: 需要旋转的节点指针
函数说明: 将左节点旋转到右边并设置为红色
返回值: 旋转后的树根指针
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Roright(Node<K, V>* node)
{
Node<K, V>* left = node->left;
node->left = left->right;
left->right = node;
left->color = node->color;
node->color = RED;
node->N = size(node->left) + size(node->right) + 1;
left->N = size(left->left) + size(left->right) + 1;
return left;
}
/********************************************************************
函数名称: flipNode
函数参数: 节点指针
函数说明: 将节点的左右子树的颜色变成黑色 同时节点颜色变成红色
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::filpNode(Node<K, V>* node)
{
node->color = RED;
node->left->color = BLACK;
node->right->color = BLACK;
}
/********************************************************************
函数名称: ReFilpNode
函数参数: @node 节点指针
函数说明: 反向翻转节点和子节点的颜色 将节点颜色变成黑色 子节点红色
返回值: 无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::ReFilpNode(Node<K, V>* node)
{
node->color = BLACK;
node->left->color = RED;
node->right->color = RED;
}
/********************************************************************
函数名称: fixRedNode
函数参数: @node 节点指针
函数说明: 修复反向反转后节点 node->right->left 为红色的情况
返回值:
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::fixNode(Node<K, V>* node)
{
node->right = Roright(node->right);
node = Roleft(node);
return node;
}
/********************************************************************
函数名称: minKey
函数参数: 无
函数说明: 返回表中最小的key
返回值: key
*********************************************************************/
template<typename K, typename V>
K RBT<K, V>::minKey() const
{
return minKey(this->root);
}
template<typename K, typename V>
K RBT<K, V>::minKey(Node<K, V>* node) const
{
if (node->left == NULL)
return node->key;
else
minKey(node->left);
}
/********************************************************************
函数名称: MaxKey
函数参数: 无
函数说明: 返回红黑树中最大的key
返回值: key
*********************************************************************/
template<typename K, typename V>
K RBT<K, V>::MaxKey() const
{
return MaxKey(this->root);
}
template<typename K, typename V>
K RBT<K, V>::MaxKey(Node<K, V>* node) const
{
if (node->right == NULL)
return node->key;
else
MaxKey(node->right);
}
template<typename K, typename V>
K RBT<K, V>::CountLevel() const
{
return CountLevel(this->root);
}
template<typename K, typename V>
K RBT<K, V>::CountLevel(Node<K, V>* node) const
{
static int count = 0;
if (node)
{
if (node->left == NULL&&node->right == NULL)
++count;
CountLevel(node->left);
CountLevel(node->right);
}
return count;
}
#endif
void test()
{
RBT<int, int>RBT;
int arr[11] = { 15, 6, 18, 3, 7, 17, 20, 2, 4, 13, 9 };
//int arr[5] = { 3, 5, 6, 2, 4 };
int index = sizeof(arr) / sizeof(arr[0]);
Node<int, int>*ret = NULL;
for (int i = 0; i < 11; i++)
{
ret = RBT.Insert(arr[i], i);
}
ret->color = BLACK;
RBT.Del(arr, index, 3);
RBT.midtree();
cout << endl;
cout << RBT.minKey() << endl;
cout << RBT.MaxKey() << endl;
cout << RBT.Getval(6) << endl;
cout << RBT.size() << endl;
cout << RBT.CountLevel() << endl;
cout << RBT.contain(6) << endl;
RBT.pretree();
cout << endl;
RBT.lasttree();
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}
3.红黑树和AVL树的比较
红黑树和AVL树都是高效的平衡二叉树, 增删查改的时间复杂度都是O(lg(N))
红黑树的不追求完全平衡, 保证最长路径不超过最短路径的2倍, 相对而言, 降低了旋转的要求, 所以性能会优于AVL树, 所以实际运用
中红黑树更多。
177万+

被折叠的 条评论
为什么被折叠?



