紅黑樹的c++代碼實現,包含測試

紅黑樹的插入,刪除幾種狀況,算法導論,已經寫得很詳細了,下面給出具體的實現代碼,包含,插入,查找,刪除。修改比較簡單,查找到該點,給key從新賦值,便可。ios

#ifndef RB_TREE_H
#define RB_TREE_H

#include<vector>
const int BLACK = -1;
const int RED = 1;


static int number1 = 0;
static int number2 = 0;
static int number3 = 0;
static int number4 = 0;
static int number5 = 0;
static int number6 = 0;


struct RB_TREE_NODE{

public:
    RB_TREE_NODE(int a)
    {
        key = a;
        color = BLACK;
        p =0;
        left = 0;
        right = 0;
    }
    ~RB_TREE_NODE()
    {
    }
    int key;
    int color;
    RB_TREE_NODE* p;
    RB_TREE_NODE* left;
    RB_TREE_NODE* right;
    
};

static RB_TREE_NODE NIL = { 0 };
#define PNIL (&NIL) 

struct RB_TREE
{
    RB_TREE()
    {
        root->left = PNIL;
        root->right = PNIL;
        root->p = PNIL;
    }
    RB_TREE_NODE* root=PNIL;

    ////插入節點z
    void RB_TREE_INSERT(RB_TREE* root, RB_TREE_NODE* z);
    ///插入節點z後對該樹進行調整,使之從新知足紅黑樹的條件
    void RB_TREE_INSERT_FIXUP(RB_TREE*root, RB_TREE_NODE* z);

    ////刪除節點z
    void RB_TREE_DELETE(RB_TREE* root, RB_TREE_NODE* z);
    ///刪除節點z後對該樹進行調整,使該樹從新知足紅黑樹的條件
    void RB_TREE_DELETE_FIXUP(RB_TREE* root, RB_TREE_NODE*z);


    ///x的前驅,不然返回nullptr
    RB_TREE_NODE*  RB_TREE_PREDECESSOR(RB_TREE* root, RB_TREE_NODE* x);
    ///x的後驅,不然返回nullptr
    RB_TREE_NODE*  RB_TREE_SUCCESSOR(RB_TREE* root, RB_TREE_NODE* x);


    ///以x爲根的樹中最小值
    RB_TREE_NODE* RB_TREE_MINMUM(RB_TREE_NODE* x);
    ///以x爲根的樹中的最大值
    RB_TREE_NODE* RB_TREE_MAXMUM(RB_TREE_NODE* x);


    ///對x節點進行左旋轉
    void RB_LEFT_ROTATE(RB_TREE* root, RB_TREE_NODE* x);
    ///對x節點進行右旋轉
    void RB_RIGHT_ROTATE(RB_TREE*root, RB_TREE_NODE* x);


    ///用以節點v爲根的樹替換以節點u爲根的樹
    void RB_TRANSPLANT(RB_TREE* root, RB_TREE_NODE* u, RB_TREE_NODE*v);
    ///搜索節點值爲value的節點,並返回,搜索不到返回PNIL
    RB_TREE_NODE* RB_SEARCH(RB_TREE* root, int value);

    ////搜索全部節點值爲value的節點並返回
    std::vector<RB_TREE_NODE*> RB_SEARCH_ALL(RB_TREE* root, int value);
};


void RB_TREE::RB_TREE_INSERT(RB_TREE* root, RB_TREE_NODE* z)
{
    z->left = PNIL;    ////哨兵並不是空節點,new 出的RB_TREE_NODE的左右孩子爲空節點不是哨兵,因此插入前,先將左右孩子置爲哨兵
    z->right = PNIL;
    RB_TREE_NODE* x = RB_TREE::root;
    RB_TREE_NODE* y=PNIL;
    while (x != PNIL)
    {
        y = x;
        if (z->key < x->key)
            x = x->left;
        else
            x = x->right;
    }
    z->p = y;
    if (y == PNIL)root->root = z;
    else if (z->key < y->key)y->left = z;
    else y->right = z;
    z->color = RED;
    RB_TREE_INSERT_FIXUP(root, z);
}

void RB_TREE::RB_TREE_INSERT_FIXUP(RB_TREE* root, RB_TREE_NODE*z)
{
    while (z->p->color == RED&&z->p != PNIL)
    {
        if (z->p->p->left == z->p)
        {
            RB_TREE_NODE* y = z->p->p->right;
            if (y->color == RED)
            {
                number1++;
                z->p->color = BLACK;
                y->color = BLACK;
                z->p->p->color = RED;
                z = z->p->p;
            }
            else
            {
                number2++;
                if (z == z->p->right)
                {
                    number3++;
                    z = z->p;
                    RB_LEFT_ROTATE(root, z);
                }            
                z->p->color = BLACK;
                z->p->p->color = RED;
                RB_RIGHT_ROTATE(root, z->p->p);
            }
        }
        else
        {
            RB_TREE_NODE* y = z->p->p->left;
            if (y->color == RED)
            {
                number4++;
                z->p->color = BLACK;
                y->color = BLACK;
                z->p->p->color = RED;
                z = z->p->p;
            }
            else
            {
                number5++;   
                if (z == z->p->left)
                {
                    number6++;
                    z = z->p;
                    RB_RIGHT_ROTATE(root, z);
                }
                z->p->color = BLACK;
                z->p->p->color = RED;
                RB_LEFT_ROTATE(root, z->p->p);
            }
        }
    }
    root->root->color = BLACK;
}

void RB_TREE::RB_LEFT_ROTATE(RB_TREE* root, RB_TREE_NODE* x)
{
    RB_TREE_NODE* y = x->right;
    x->right = y->left;
    if (y->left!=PNIL)
    y->left->p = x;
    y->p = x->p;
    if (x->p == PNIL)root->root = y;
    else if (x->p->left ==x)x->p->left = y;
    else x->p->right = y;
    x->p = y;
    y->left = x;
}

void RB_TREE::RB_RIGHT_ROTATE(RB_TREE*root, RB_TREE_NODE* x)
{
    RB_TREE_NODE* y = x->left;
    x->left = y->right;
    if (y->right != PNIL)
        y->right->p = x;
    y->p = x->p; 
    if (x->p == PNIL)root->root = y;
    else if (x->p->left == x) x->p->left = y;
    else x->p->right = y;
    x->p = y;
    y->right = x;
}

RB_TREE_NODE*  RB_TREE::RB_TREE_PREDECESSOR(RB_TREE* root, RB_TREE_NODE* x)
{
    if (x == RB_TREE_MINMUM(root->root))return x;
    if (x->left != PNIL)return RB_TREE_MAXMUM(x->left);
    RB_TREE_NODE* y = x->p;
    while (y != PNIL&&x == y->left)
    {
        x = y;
        y = y->p;
    }
    return y;
}

RB_TREE_NODE*  RB_TREE::RB_TREE_SUCCESSOR(RB_TREE* root, RB_TREE_NODE* x)
{
    if (x == RB_TREE_MAXMUM(root->root))return x;
    if (x->right != PNIL)return RB_TREE_MINMUM(x->right);
    RB_TREE_NODE* y = x->p;
    while (y != PNIL&&x == y->right)
    {
        x = y;
        y = y->p;
    }
    return y;
}

RB_TREE_NODE* RB_TREE::RB_TREE_MINMUM(RB_TREE_NODE* x)
{
    while (x->left != PNIL)
        x = x->left;
    return x;
}

RB_TREE_NODE* RB_TREE::RB_TREE_MAXMUM(RB_TREE_NODE* x)
{
    while (x->right != PNIL)
        x = x->right;
    return x;
}

void RB_TREE::RB_TRANSPLANT(RB_TREE* root, RB_TREE_NODE* u, RB_TREE_NODE* v)
{
    if (u->p == PNIL)root->root = v;
    else if (u == u->p->left)u->p->left=v;
    else u->p->right = v;
    if (v!=PNIL)
    v->p = u->p;
}

RB_TREE_NODE* RB_TREE::RB_SEARCH(RB_TREE* root, int value)
{
    //  此爲刪除第一個值爲value的節點
    RB_TREE_NODE* temp = root->root;
    while (temp != PNIL&&temp->key != value)
    {
        if (value < temp->key)
        {
            temp = temp->left;
        }
        else
        {
            temp = temp->right;
        }
    }
    return temp;
}

std::vector<RB_TREE_NODE*> RB_TREE::RB_SEARCH_ALL(RB_TREE* root, int value)
{
    std::vector<RB_TREE_NODE*>result;

    RB_TREE_NODE* temp = root->root;
    while (temp != PNIL&&temp->key != value)
    {
        if (value < temp->key)
        {
            temp = temp->left;
        }
        else
        {
            temp = temp->right;
        }
    }
    result.push_back(temp);
    RB_TREE_NODE* temp2 = temp;
    while(temp != PNIL)            /////尋找temp的前驅值相等的
    {
        RB_TREE_NODE* t1 = RB_TREE_PREDECESSOR(root, temp);
        if (t1!=PNIL&&t1->key == temp->key)
            result.push_back(t1);
        else break;
        temp = t1;
    }

    temp = temp2;
    while (temp!=PNIL)          ////尋找temp的後驅值相等的
    {
        RB_TREE_NODE* t1 = RB_TREE_SUCCESSOR(root, temp);
        if (t1!=PNIL&&t1->key==temp->key)
          result.push_back(t1);
        else break;
        temp = t1;
    }
    return result;
}

void RB_TREE::RB_TREE_DELETE(RB_TREE* root, RB_TREE_NODE* z)
{
    RB_TREE_NODE* y = z;
    RB_TREE_NODE* x;
    int origin_color = y->color;

    if (z->left == PNIL)
    {
        x = z->right;
        RB_TRANSPLANT(root, z, z->right);
    }
    else if (z->right == PNIL)
    {
        x = z->left;
        RB_TRANSPLANT(root, z, z->left);
    }
    else
    {
        y = RB_TREE_MINMUM(z->right);
        origin_color = y->color;
        x = y->right;
        if (y->p == z)
        {
            x->p = y;   ////防止y的子節點都是哨兵,進行刪除調整時,須要找到x的父節點,而哨兵沒有父節點。
        }
        else
        {
            RB_TRANSPLANT(root, y, y->right);
            y->right = z->right;
            y->right->p = y;        
        }
        RB_TRANSPLANT(root, z, y);
        y->left = z->left;
        y->left->p = y;
        y->color = z->color;

        z->p = nullptr;      ///////刪除節點z時,對父節點,子節點指針置爲空,只刪除節點z的區域
        z->right = nullptr;
        z->left = nullptr;
        delete z;
    }
    if (origin_color == BLACK)
    {
        RB_TREE_DELETE_FIXUP(root, x);
    }
}

void RB_TREE:: RB_TREE_DELETE_FIXUP(RB_TREE* root, RB_TREE_NODE*z)
{
    while (z != root->root&&z->color == BLACK)
    {
        if (z == z->p->left)
        {
            RB_TREE_NODE* y = z->p->right;
            if (y->color == RED)   /////case1
            {
                y->color = BLACK;
                z->p->color = RED;
                RB_LEFT_ROTATE(root, z->p);
                y = z->p->right;   ////轉到case2,3,4中的一種
            }
            if (y->left->color == BLACK&&y->right->color == BLACK)
            {
                y->color = RED;    ////case2
                z = z->p;
            }
            else
            {
                if (y->right->color == BLACK)
                {
                    y->left->color = BLACK;
                    y->color = RED;
                    RB_RIGHT_ROTATE(root, y);   ////case3 轉到case4
                    y = z->p->right;
                }
                y->color = z->p->color;
                z->p->color = BLACK;          ////case4;
                y->right->color = BLACK;
                RB_LEFT_ROTATE(root, z->p);
                z = root->root;
            }
        }
        else             ////與以上left和right互換
        {
            RB_TREE_NODE* y = z->p->left;
            if (y->color == RED)
            {
                y->color = BLACK;
                z->p->color = RED;
                RB_RIGHT_ROTATE(root, z->p);
                y = z->p->left;
            }
            if (y->right->color == BLACK&&y->left->color == BLACK)
            {
                y->color = RED;
                z = z->p;
            }
            else
            {
                if (y->left->color == BLACK)
                {
                    y->right->color = BLACK;
                    y->color = RED;
                    RB_LEFT_ROTATE(root, y);
                    y = z->p->left;
                }
                y->color = z->p->color;
                z->p->color = BLACK;
                y->left->color = BLACK;
                RB_RIGHT_ROTATE(root, z->p);
                z = root->root;
            }
        }
    }
    z->color = BLACK;
}
#endif

測試主函數算法

#include"RB_TREE1.h"
#include<iostream>
using namespace std;


void print(RB_TREE* root)    /////從小到大輸出全部的樹節點值
{
    RB_TREE_NODE* pmin = root->RB_TREE_MINMUM(root->root);
    RB_TREE_NODE* pmax = root->RB_TREE_MAXMUM(root->root);
    int i = 0;
    while (true)
    {
        if (i++ % 10 == 0)cout << endl;
        cout << pmin->key << " ";
        if (pmin == pmax)break;
        pmin = root->RB_TREE_SUCCESSOR(root, pmin);
    }

    cout <<endl<< endl << "++++++++++++++++++++++++++++++++++++++" << endl;
}
int main()
{
    int a[1000];
    for (int i = 0; i < 1000; i++)
    {
        a[i] = rand() % 100;
    }

    RB_TREE* root = new RB_TREE();
    for (int i = 0; i < 100; i++)
    {
        RB_TREE_NODE* z = new RB_TREE_NODE(a[i]);
        root->RB_TREE_INSERT(root,z);
    }
    
    cout << "++++++++++++++++++++++++++++++++++++++" << endl;
    RB_TREE_NODE* pmin = root->RB_TREE_MINMUM(root->root);
    RB_TREE_NODE* pmax = root->RB_TREE_MAXMUM(root->root);
    print(root);
    cout << endl << endl << "++++++++++++++++++++++++++++++++" << endl;
    
        
    vector<RB_TREE_NODE*>result1 = root->RB_SEARCH_ALL(root, 50);
    for (RB_TREE_NODE* temp : result1)
    {
        cout << temp->key << " ";
    }

    vector<RB_TREE_NODE*>result2 = root->RB_SEARCH_ALL(root, 29);
    for (RB_TREE_NODE* temp : result2)
    {
        cout << temp->key << " ";
    }

    vector<RB_TREE_NODE*>result3 = root->RB_SEARCH_ALL(root, 82);
    for (RB_TREE_NODE* temp : result3)
    {
        cout << temp->key << " ";
    }

    cout << endl << "++++++++++++++++++++++++++++++++++++++" << endl;
    
    
    for (RB_TREE_NODE* temp : result1)
    {
        if (temp != PNIL)root->RB_TREE_DELETE(root,temp);
    }
    print(root);
    for (RB_TREE_NODE* temp : result2)
    {
        if (temp != PNIL)root->RB_TREE_DELETE(root, temp);
    }
    print(root);
    for (RB_TREE_NODE* temp : result3)
    {
        if (temp != PNIL)root->RB_TREE_DELETE(root, temp);
    }
    print(root);
    
    /////對應插入的case狀況
    cout << endl << number1 << " " << number2 << " " << number3 << " " << number4 << " " << number5 << " " << number6 << endl;
    cout << endl << "====================" << endl;
    cout << root->root->key << " " << root->root->color << endl;

    cout << root->root->left->key << " " << root->root->left->color << endl;
    cout << root->root->right->key << " " << root->root->right->color << endl;

    cout << root->root->left->left->key << " " << root->root->left->left->color << endl;
    cout << root->root->left->right->key << " " << root->root->left->right->color << endl;

    cout << root->root->right->left->key << " " << root->root->right->left->color << endl;
    cout << root->root->right->right->key << " " << root->root->right->right->color << endl;
    

}

手動測試劃出11個元素的紅黑樹,與筆畫出的結果一致。函數

相關文章
相關標籤/搜索