红黑树(红黑树研究记录-代码实现)

代码可以根据《红黑树研究记录-实例》那篇文章的图来验证

main.cpp

复制代码
#include <iostream.h>
#include "RBTree.h"

using namespace std;

int main(int argc, char *argv[])
{
    int arr[20] = {12, 1, 9, 2, 0, 11, 7, 19, 4, 15, 18, 5, 14, 13, 10, 16, 6, 3, 8, 17};
    RBTree *tree = new RBTree();
    for(int i = 0; i < 20; i++)
        tree->InsertNode(arr[i]);
    
    
    std::cout<<"PreOrder:"<<std::endl;
    tree->PreOrder();
    std::cout<<"InOrder:"<<std::endl;
    tree->InOrder();
    std::cout<<"PostOrder:"<<std::endl;
    tree->PostOrder();
    
    std::cout<<std::endl<<"Delete Node:"<<std::endl;
    cout<<"Delete 12:"<<endl;
    tree->DeleteNode(12);
    tree->PreOrder();
    cout<<"Delete 1:"<<endl;
    tree->DeleteNode(1);
    tree->PreOrder();
    cout<<"Delete 9:"<<endl;
    tree->DeleteNode(9);
    tree->PreOrder();
    cout<<"Delete 2:"<<endl;
    tree->DeleteNode(2);
    tree->PreOrder();    
    cout<<"Delete 0:"<<endl;
    tree->DeleteNode(0);
    tree->PreOrder();
    cout<<"Delete 11:"<<endl;
    tree->DeleteNode(11);
    tree->PreOrder();
    cout<<"Delete 7:"<<endl;
    tree->DeleteNode(7);
    tree->PreOrder();
    cout<<"Delete 19:"<<endl;
    tree->DeleteNode(19);
    tree->PreOrder();
    cout<<"Delete 4:"<<endl;
    tree->DeleteNode(4);
    tree->PreOrder();
    cout<<"Delete 15:"<<endl;
    tree->DeleteNode(15);
    tree->PreOrder();    
    cout<<"Delete 18:"<<endl;
    tree->DeleteNode(18);
    tree->PreOrder();
    cout<<"Delete 5:"<<endl;
    tree->DeleteNode(5);
    tree->PreOrder();
    cout<<"Delete 14:"<<endl;
    tree->DeleteNode(14);
    tree->PreOrder();
    cout<<"Delete 13:"<<endl;
    tree->DeleteNode(13);
    tree->PreOrder();
    cout<<"Delete 10:"<<endl;
    tree->DeleteNode(10);
    tree->PreOrder();    
    cout<<"Delete 6:"<<endl;
    tree->DeleteNode(6);
    tree->PreOrder();
    cout<<"Delete 16:"<<endl;
    tree->DeleteNode(16);
    tree->PreOrder();
    cout<<"Delete 3:"<<endl;
    tree->DeleteNode(3);
    tree->PreOrder();
    cout<<"Delete 8:"<<endl;
    tree->DeleteNode(8);
    tree->PreOrder();
    cout<<"Delete 17:"<<endl;
    tree->DeleteNode(17);
    tree->PreOrder();
    return  0;
}
复制代码

RBTree.h

复制代码
#ifndef _RBTREE_HEADER_
#define _RBTREE_HEADER_

#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>

enum NodeColor{
    RED,
    BLACK
};

struct RBNode
{
    int value;
    NodeColor color;
    RBNode *pParent;
    RBNode *pLeft;
    RBNode *pRight;
};

class RBTree
{
public:
    RBTree();
    ~RBTree();
    
    int InsertNode(int);
    int DeleteNode(int);
    RBNode *FindNode(int value);
    
    void PreOrder();
    void InOrder();
    void PostOrder();
private:
    void DeleteAll();
    void TurnLeft(RBNode *pNode);
    void TurnRight(RBNode *pNode);
    int DeleteNode(RBNode *);
    RBNode *GetSuccessor(RBNode *);
    int InsertNode(RBNode *);
    void DeleteFixup(RBNode *);
    void InsertFixup(RBNode *);
private:
    RBNode *m_root;
};

#endif
复制代码

RBTree.cpp

复制代码
#include "RBTree.h"
#include <deque>
#include <queue>

using namespace std;

RBTree::RBTree()
{
    m_root = NULL;
}

RBTree::~RBTree()
{
    DeleteAll();
}

void RBTree::TurnLeft(RBNode *pNode)
{
    if(!pNode || !pNode->pParent)
        return;
    RBNode *pp = pNode->pParent->pParent;
    if(pp)
        if(pp->pLeft == pNode->pParent)
            pp->pLeft = pNode;
        else
            pp->pRight = pNode;
    pNode->pParent->pParent = pNode;
    pNode->pParent->pRight = pNode->pLeft;
    if(pNode->pLeft)
        pNode->pLeft->pParent = pNode->pParent;
    pNode->pLeft = pNode->pParent;    
    pNode->pParent = pp;    
}

void RBTree::TurnRight(RBNode *pNode)
{
    if(!pNode || !pNode->pParent)
        return;
    RBNode *pp = pNode->pParent->pParent;
    if(pp)
        if(pp->pLeft == pNode->pParent)
            pp->pLeft = pNode;
        else
            pp->pRight = pNode;
    pNode->pParent->pParent = pNode;
    pNode->pParent->pLeft = pNode->pRight;
    if(pNode->pRight)
        pNode->pRight->pParent = pNode->pParent;
    pNode->pRight = pNode->pParent;    
    pNode->pParent = pp;
}

void RBTree::DeleteAll()
{
    if(!m_root)
        std::cout<<"The tree is null"<<std::endl;
    queue<RBNode*> qu;
    qu.push(m_root);
    while(qu.size() > 0)
    {
        RBNode *pCur = qu.front();
        qu.pop();
        std::cout<<"Delete:"<<pCur->value<<"("<<pCur->color<<"), "<<std::endl;
        if(pCur->pLeft)
            qu.push(pCur->pLeft);
        if(pCur->pRight)
            qu.push(pCur->pRight);
        delete pCur;
        pCur = NULL;
    }
}

int RBTree::InsertNode(int value)
{
    if(FindNode(value))
        return -1;
    RBNode *pNew = new RBNode();
    pNew->value = value;
    pNew->pParent = NULL;
    pNew->color = RED;
    pNew->pLeft = NULL;
    pNew->pRight = NULL;
    
    return InsertNode(pNew);
}

int RBTree::InsertNode(RBNode* pNode)
{
    if(!pNode)
        return -1;
    if(!m_root)
    {
        m_root = pNode;
        m_root->color = BLACK;
        return 0;
    }
    RBNode *tmp = m_root;
    RBNode *tmpParent = NULL;
    while(tmp)
    {
        tmpParent = tmp;
        if(tmp->value > pNode->value)
            tmp = tmp->pLeft;
        else
            tmp = tmp->pRight;
    }
    if(tmpParent->value > pNode->value)
        tmpParent->pLeft = pNode;
    else
        tmpParent->pRight = pNode;
    pNode->pParent = tmpParent;
    
    InsertFixup(pNode);
}

void RBTree::InsertFixup(RBNode *pNode)
{
    if(!pNode)
        return;
    RBNode *pUncle = NULL;
    while(pNode->pParent && pNode->pParent->color == RED)
    {
        if(pNode->pParent == pNode->pParent->pParent->pLeft)
        {
            pUncle = pNode->pParent->pParent->pRight;
            if(pUncle && pUncle->color == RED)            //case 1
            {
                pNode->pParent->color = BLACK;
                pUncle->color = BLACK;
                pNode->pParent->pParent->color = RED;
                pNode = pNode->pParent->pParent;
            }
            else
            {
                if(pNode == pNode->pParent->pRight)        //case 2
                {
                    TurnLeft(pNode);
                    pNode = pNode->pLeft;
                }
                pNode->pParent->color = BLACK;            //case 3
                pNode->pParent->pParent->color = RED;
                TurnRight(pNode->pParent);
                if(!pNode->pParent->pParent)
                    m_root = pNode->pParent;
            }
        }
        else
        {
            pUncle = pNode->pParent->pParent->pLeft;
            if(pUncle && pUncle->color == RED)                    //case 1
            {
                pNode->pParent->color = BLACK;
                pUncle->color = BLACK;
                pNode->pParent->pParent->color = RED;
                pNode = pNode->pParent->pParent;
            }
            else
            {
                if(pNode == pNode->pParent->pLeft)        //case 2
                {
                    TurnRight(pNode);
                    pNode = pNode->pRight;
                }
                pNode->pParent->color = BLACK;            //case 3
                pNode->pParent->pParent->color = RED;
                TurnLeft(pNode->pParent);
                if(!pNode->pParent->pParent)
                    m_root = pNode->pParent;
            }
        }
    }
    m_root->color = BLACK;
}

int RBTree::DeleteNode(int value)
{
    RBNode *pNode = NULL;
    if(!(pNode = FindNode(value)))
        return -1;
    return DeleteNode(pNode);
}

RBNode *RBTree::GetSuccessor(RBNode *pNode)
{
    RBNode *pThis = pNode->pRight;
    while(pThis->pLeft)
        pThis = pThis->pLeft;
    return pThis;
}

int RBTree::DeleteNode(RBNode *pNode)
{
    if(!pNode)
        return -1;
    RBNode *pDel = NULL;
    RBNode *pThis = NULL;
    //search the Node
    if(!pNode->pLeft && !pNode->pRight)
    {
        pThis = pNode;
        pDel = pNode;
    }
    else if(!pNode->pLeft || !pNode->pRight)
        pDel = pNode;
    else
        pDel = GetSuccessor(pNode);
    
    //delete the Node
    if(pDel->pLeft)
        pThis = pDel->pLeft;
    else if(pDel->pRight)
        pThis = pDel->pRight;
    else
        pThis = pDel;
    
    if(pThis != pDel)
    {
        pThis->pParent = pDel->pParent;
        
        if(!pDel->pParent)
            m_root = pThis;
        else if(pDel == pDel->pParent->pLeft)
            pDel->pParent->pLeft = pThis;
        else
            pDel->pParent->pRight = pThis;
    }
    if(pDel != pNode)
        pNode->value = pDel->value;
    if(pDel->color == BLACK)
        DeleteFixup(pThis);
        
    if(pThis == pDel)
        if(pDel == pDel->pParent->pLeft)
            pDel->pParent->pLeft = NULL;
        else
            pDel->pParent->pRight = NULL;
    if(pDel == m_root)
        m_root = NULL;
    delete pDel;
    pDel = NULL;
}

void RBTree::DeleteFixup(RBNode *pNode)
{
    RBNode *pBrother = NULL;
    while(pNode != m_root && pNode->color == BLACK)
    {
        if(pNode == pNode->pParent->pLeft)
        {
            pBrother = pNode->pParent->pRight;
            if(pBrother->color == RED)        //case 1
            {
                pBrother->color = BLACK;
                pNode->pParent->color = RED;
                TurnLeft(pBrother);
                pBrother = pNode->pParent->pRight;    
            }
            if((!pBrother->pLeft || pBrother->pLeft->color == BLACK) 
                && (!pBrother->pRight || pBrother->pRight->color == BLACK))        //case 2
            {
                pBrother->color = RED;
                pNode = pNode->pParent;
            }
            else
            {
                if(!pBrother->pRight || pBrother->pRight->color == BLACK)        //case 3
                {
                    pBrother->pLeft->color = BLACK;
                    pBrother->color = RED;
                    TurnRight(pBrother->pLeft);
                    pBrother = pNode->pParent->pRight;
                }
                pBrother->color = pNode->pParent->color;    //case 4
                pNode->pParent->color = BLACK;
                pBrother->pRight->color = BLACK;
                TurnLeft(pBrother);
                pNode = m_root;
            }
        }
        else
        {
            pBrother = pNode->pParent->pLeft;
            if(pBrother->color == RED)        //case 1
            {
                pBrother->color = BLACK;
                pNode->pParent->color = RED;
                TurnRight(pBrother);
                pBrother = pNode->pParent->pLeft;
            }
            if((!pBrother->pLeft || pBrother->pLeft->color == BLACK) 
                && (!pBrother->pRight || pBrother->pRight->color == BLACK))    //case 2
            {
                pBrother->color = RED;
                pNode = pNode->pParent;
            }
            else
            {
                if(!pBrother->pLeft || pBrother->pLeft->color == BLACK)        //case 3
                {
                    pBrother->pRight->color = BLACK;
                    pBrother->color = RED;
                    TurnLeft(pBrother->pRight);
                    pBrother = pNode->pParent->pLeft;
                }
                pBrother->color = pNode->pParent->color;
                pNode->pParent->color = BLACK;
                pBrother->pLeft->color = BLACK;
                TurnRight(pBrother);
                pNode = m_root;
            }
        }
    }
    pNode->color = BLACK;
}

RBNode *RBTree::FindNode(int value)
{
    if(!m_root)
        return NULL;
    RBNode *tmp = m_root;
    while(tmp)
    {
        if(value > tmp->value)
            tmp = tmp->pRight;
        else if(value < tmp->value)
            tmp = tmp->pLeft;
        else
            break;
    }
    return tmp;
}

void RBTree::PreOrder()
{
    if(!m_root)
    {
        std::cout<<"The tree is null"<<std::endl;
        return;
    }
    queue<RBNode*> qu;
    qu.push(m_root);
    while(qu.size() > 0)
    {
        RBNode *pCur = qu.front();
        qu.pop();
        std::cout<<pCur->value<<"("<<pCur->color<<"), ";
        if(pCur->pLeft)
            qu.push(pCur->pLeft);
        if(pCur->pRight)
            qu.push(pCur->pRight);
    }
    std::cout<<std::endl;
}

void RBTree::InOrder()
{
    if(!m_root)
    {
        std::cout<<"The tree is null"<<std::endl;
        return;
    }
    
    deque<RBNode*> de;
    RBNode *pCur = m_root;
    bool bPush = false;
    
    while(pCur)
    {
        if(pCur->pLeft && !bPush)
        {
            de.push_back(pCur);
            pCur = pCur->pLeft;
            continue;
        }
        std::cout<<pCur->value<<"("<<pCur->color<<"), ";
        
        if(pCur->pRight)
        {
            pCur = pCur->pRight;
            bPush = false;
        }
        else
        {
            if(de.size() == 0)
                break;
            pCur = de.back();
            de.pop_back();
            bPush = true;
        }
    }
    std::cout<<std::endl;
}

void RBTree::PostOrder()
{
    if(!m_root)
    {
        std::cout<<"The tree is null"<<std::endl;
        return;
    }
    deque<RBNode*> de;
    int flag = 0;
    RBNode *pCur = m_root;
    while(pCur)
    {
        if(pCur->pLeft && flag < 1)
        {
            de.push_back(pCur);
            pCur = pCur->pLeft;
            continue;
        }
        if(pCur->pRight && flag < 2)
        {
            de.push_back(pCur);
            pCur = pCur->pRight;
            flag = 0;
            continue;
        }
        std::cout<<pCur->value<<"("<<pCur->color<<"), ";
        
        if(de.size() == 0)
            break;
        RBNode *pParent = de.back();
        de.pop_back();
        
        if(pCur == pParent->pLeft)
        {
            flag = 1;
            pCur = pParent;
        }
        else if(pCur == pParent->pRight)
        {
            flag = 2;
            pCur = pParent;
        }
    }
    std::cout<<std::endl;
}


转载地址:http://www.cnblogs.com/geekma/archive/2012/06/28/2567718.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
红黑树是一种自平衡二叉查找树,它能够保证任何一个节点的左右子树的高度差不会超过两倍。下面是C++代码实现红黑树的基本操作: ```c++ #include <iostream> using namespace std; enum Color {RED, BLACK}; struct Node { int val; Color color; Node *left, *right, *parent; Node(int v) : val(v), color(RED), left(nullptr), right(nullptr), parent(nullptr) {} }; class RBTree { private: Node *root; void rotateLeft(Node *x) { Node *y = x->right; x->right = y->left; if (y->left != nullptr) { y->left->parent = x; } y->parent = x->parent; if (x->parent == nullptr) { root = y; } else if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } y->left = x; x->parent = y; } void rotateRight(Node *x) { Node *y = x->left; x->left = y->right; if (y->right != nullptr) { y->right->parent = x; } y->parent = x->parent; if (x->parent == nullptr) { root = y; } else if (x == x->parent->right) { x->parent->right = y; } else { x->parent->left = y; } y->right = x; x->parent = y; } void insertFixup(Node *z) { while (z->parent != nullptr && z->parent->color == RED) { if (z->parent == z->parent->parent->left) { Node *y = z->parent->parent->right; if (y != nullptr && y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->right) { z = z->parent; rotateLeft(z); } z->parent->color = BLACK; z->parent->parent->color = RED; rotateRight(z->parent->parent); } } else { Node *y = z->parent->parent->left; if (y != nullptr && y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->left) { z = z->parent; rotateRight(z); } z->parent->color = BLACK; z->parent->parent->color = RED; rotateLeft(z->parent->parent); } } } root->color = BLACK; } void transplant(Node *u, Node *v) { if (u->parent == nullptr) { root = v; } else if (u == u->parent->left) { u->parent->left = v; } else { u->parent->right = v; } v->parent = u->parent; } void deleteFixup(Node *x) { while (x != root && x->color == BLACK) { if (x == x->parent->left) { Node *w = x->parent->right; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rotateLeft(x->parent); w = x->parent->right; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->parent; } else { if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; rotateRight(w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = BLACK; w->right->color = BLACK; rotateLeft(x->parent); x = root; } } else { Node *w = x->parent->left; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; rotateRight(x->parent); w = x->parent->left; } if (w->right->color == BLACK && w->left->color == BLACK) { w->color = RED; x = x->parent; } else { if (w->left->color == BLACK) { w->right->color = BLACK; w->color = RED; rotateLeft(w); w = x->parent->left; } w->color = x->parent->color; x->parent->color = BLACK; w->left->color = BLACK; rotateRight(x->parent); x = root; } } } x->color = BLACK; } public: RBTree() : root(nullptr) {} Node* search(int v) { Node *cur = root; while (cur != nullptr && cur->val != v) { if (cur->val > v) { cur = cur->left; } else { cur = cur->right; } } return cur; } void insert(int v) { Node *z = new Node(v); Node *y = nullptr; Node *x = root; while (x != nullptr) { y = x; if (z->val < x->val) { x = x->left; } else { x = x->right; } } z->parent = y; if (y == nullptr) { root = z; } else if (z->val < y->val) { y->left = z; } else { y->right = z; } insertFixup(z); } void remove(int v) { Node *z = search(v); if (z == nullptr) { return; } Node *y = z; Color yOriginalColor = y->color; Node *x; if (z->left == nullptr) { x = z->right; transplant(z, z->right); } else if (z->right == nullptr) { x = z->left; transplant(z, z->left); } else { y = z->right; while (y->left != nullptr) { y = y->left; } yOriginalColor = y->color; x = y->right; if (y->parent == z) { x->parent = y; } else { transplant(y, y->right); y->right = z->right; y->right->parent = y; } transplant(z, y); y->left = z->left; y->left->parent = y; y->color = z->color; } if (yOriginalColor == BLACK) { deleteFixup(x); } delete z; } void print() { printHelper(root, 0); } void printHelper(Node *cur, int depth) { if (cur == nullptr) { return; } printHelper(cur->right, depth + 1); for (int i = 0; i < depth; ++i) { cout << "\t"; } cout << cur->val << "(" << cur->color << ")" << endl; printHelper(cur->left, depth + 1); } }; int main() { RBTree tree; tree.insert(3); tree.insert(1); tree.insert(4); tree.insert(6); tree.insert(9); tree.insert(2); tree.insert(5); tree.insert(7); tree.insert(8); tree.print(); cout << endl; tree.remove(3); tree.remove(5); tree.print(); return 0; } ``` 在这段代码中,我们定义了一个`Node`结构体,表示红黑树的节点。它包含了节点值`val`、节点颜色`color`、左右子节点指针`left`和`right`、父节点指针`parent`。 我们还定义了一个`RBTree`类,表示红黑树。它包含了`root`节点指针,表示红黑树的根节点。 在`RBTree`类中,我们实现了如下操作: - `search`:在红黑树中查找某个值,返回相应节点指针。 - `insert`:向红黑树中插入一个值,保证插入后仍然是红黑树。 - `remove`:从红黑树中删除一个值,保证删除后仍然是红黑树。 - `print`:打印红黑树的结构。 其中,`insert`和`remove`操作中,我们还实现红黑树的自平衡调整函数`insertFixup`和`deleteFixup`,保证插入和删除后仍然是红黑树

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值