红黑树

来源:互联网 发布:开淘宝店挣钱么 编辑:程序博客网 时间:2024/06/04 17:58

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;}#endifvoid 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树, 所以实际运用
中红黑树更多。

原创粉丝点击