redBlackTree


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

using namespace std;

enum _CORLOR{
    BLACK = 0,
    RED,
    MAX_CORLOR
};

template<class elemType>
struct rbNode{
    rbNode<elemType> *lLink;//left child node
    rbNode<elemType> *rLink;//right child node
    rbNode<elemType> *pLink;//point to parent node
    elemType info;
    int corlor;
};

rbNode<int> nil = {NULL, NULL, NULL, 0x7fffffff, BLACK};

template<class elemType>
rbNode<elemType>* findElem(rbNode<elemType> *root, elemType info)
{
    rbNode<elemType> *pTmp = NULL;
    if(root != NULL)
    {
        if(info == root->info)
        {
            return root;
        }
        if( root->info > info && root->lLink != &nil)
        {
            return findElem(root->lLink, info);
        }
        printf(" %d\n", root->info);
        if(root->info < info && root->rLink != &nil)
        {
            return findElem(root->rLink, info);
        }
    }

    return NULL; 
}

template<class elemType>
rbNode<elemType>* successorElem(rbNode<elemType> *node)
{
    rbNode<elemType> *pTmp = node;
    rbNode<elemType> *pRes = &nil;
    if(node == &nil)
    {
        printf("error: input node is nil\n");
        return NULL;
    }
    if(pTmp != &nil && pTmp->rLink != &nil)
    {
        while(pTmp->lLink != &nil)
        {
            pTmp = pTmp->lLink;
        }
        pRes = pTmp->pLink;
        return pRes;
    }
    while(pTmp != &nil && pTmp->pLink != &nil)
    {
        if(pTmp == pTmp->pLink->rLink)//
        {
            pTmp = pTmp->pLink;
        }
        else
        {
            pRes = pTmp;
            break;
        }
    }

    return pRes; 
}


template<class elemType>
int left_rotate(rbNode<elemType> *root)
{
    if(root == &nil)
    {
        printf("error:input root is NULL\n");
        return 0;
    }
    if(root->rLink == &nil)
    {
        printf("error:right sub tree of root is NULL\n");
        return 0;
    }
    rbNode<elemType> *pTmp = root->rLink;
    root->rLink = pTmp->lLink;
    if(root->rLink != &nil)
    {
        root->rLink->pLink = root;
    }
    pTmp->pLink = root->pLink;
    if(pTmp->pLink->lLink == root)
    {
        pTmp->pLink->lLink = pTmp;
    }
    else
    {
        pTmp->pLink->rLink = pTmp;
    }
    root->pLink = pTmp;
    root->pLink = pTmp;
    pTmp->lLink = root;

    return 0;
}

template<class elemType>
int right_rotate(rbNode<elemType> *root)
{
    if(root == &nil)
    {
        printf("error:input root is NULL\n");
        return 0;
    }
    if(root->lLink == &nil)
    {
        printf("error:right sub tree of root is NULL\n");
        return 0;
    }
    rbNode<elemType> *pTmp = root->lLink;
    root->lLink = pTmp->rLink;
    if(root->lLink != &nil)
    {
        root->lLink->pLink = root;
    }
    pTmp->pLink =  root->pLink;
    if(pTmp->pLink->lLink == root)
    {
        pTmp->pLink->lLink = pTmp;
    }
    else
    {
        pTmp->pLink->rLink = pTmp;
    }
    root->pLink = pTmp;
    pTmp->rLink = root;

    return 0;
}

template<class elemType>
int rb_insert_fixup(rbNode<elemType> **root, rbNode<elemType> *newNode)
{
    rbNode<elemType> *pTmpX = newNode;
    while(pTmpX->pLink->corlor == RED)
    {
        //printf("%s(%d): cur node %d, parent node %d\n", 
    //        __FILE__, __LINE__, pTmpX->info, pTmpX->pLink->info);
        rbNode<elemType> *pTmpFather = pTmpX->pLink;

        //if this is the left child of parent
        if( pTmpFather->pLink != &nil && pTmpFather == pTmpFather->pLink->lLink)
        {
            printf("%s(%d): cur node %d, parent node %d, grand parent %d\n", 
                __FILE__, __LINE__, pTmpX->info, pTmpX->pLink->info,
                pTmpFather->pLink->info);
            rbNode<elemType> *pTmpUncle = pTmpFather->pLink->rLink;
            if(pTmpUncle != &nil && pTmpUncle->corlor == RED)
            {
                printf("enter case 1\n");
                pTmpUncle->corlor = BLACK;
                pTmpFather->corlor = BLACK;
                pTmpFather->pLink->corlor = RED;
                pTmpX = pTmpFather->pLink;//the next process node
            }
            else
            if(pTmpX == pTmpFather->rLink)
            {
                printf("enter case 2\n");
                pTmpX= pTmpFather;//the next process node
                rbNode<elemType> *pTmpY = pTmpX;
                if(*root == pTmpY)
                {
                    *root = pTmpY->rLink;
                }
                left_rotate(pTmpY);
            }
            //case 3
            else
            {
                printf("enter case 3\n");
                pTmpX->pLink->corlor = BLACK;
                if(pTmpX->pLink->pLink != &nil)
                {
                    pTmpX->pLink->pLink->corlor = RED;
                    if(*root == pTmpX->pLink->pLink)
                    {
                        *root = pTmpX->pLink;
                    }
                    right_rotate(pTmpX->pLink->pLink);
                }
            }
        }
        //if this is the right child of parent
        else if(pTmpFather == pTmpFather->pLink->rLink)
        {
            rbNode<elemType> *pTmpUncle = pTmpFather->pLink->lLink;
            if(pTmpUncle->corlor == RED)
            {
                printf("enter r case 1\n");
                pTmpUncle->corlor = BLACK;
                pTmpFather->corlor = BLACK;
                pTmpFather->pLink->corlor = RED;
                pTmpX = pTmpFather->pLink;//the next process node
            }
            else
            if(pTmpX == pTmpFather->lLink)
            {
                printf("enter r case 2\n");
                pTmpX= pTmpFather;//the next process node
                rbNode<elemType> *pTmpY = pTmpX;
                if(*root == pTmpY)
                {
                    *root = pTmpY->lLink;
                }
                right_rotate(pTmpY);
            }
            //case 3
            else
            {
                printf("enter r case 3\n");
                pTmpX->pLink->corlor = BLACK;
                if(pTmpX->pLink->pLink != &nil)
                {
                    pTmpX->pLink->pLink->corlor = RED;
                    if(*root == pTmpX->pLink->pLink)
                    {
                        *root = pTmpX->pLink;
                    }
                    left_rotate(pTmpX->pLink->pLink);
                }
            }
        }
        (*root)->corlor = BLACK;
    }
proc_over:
    return 0;
}

template<class elemType>
int insertNode(rbNode<elemType> **root, rbNode<elemType> *newNode)
{
    rbNode<elemType> *pTmpY = &nil;
    rbNode<elemType> *pTmpX = *root;
    while(pTmpX != &nil)
    {
        printf("%s(%d):pTmpX info %d\n", __FILE__, __LINE__, pTmpX->info);
        pTmpY = pTmpX;
        if( newNode->info == pTmpX->info)
        {
            printf("error:the same info %d in the tree\n", newNode->info);
            break;
        }
        else
        if( newNode->info > pTmpX->info)
        {
            pTmpX = pTmpX->rLink;
        }
        else
        {
            pTmpX = pTmpX->lLink;
        }
    }
    //have the same node in the tree
    if(pTmpX != &nil)
    {
        printf("error:the same info in the tree\n");
        goto proc_over;
    }
    //tree has no entry yet.
    if(pTmpY == &nil)
    {
        *root = newNode;
        newNode->pLink = &nil;
    }
    else
    {
        if( newNode->info > pTmpY->info)
        {
            pTmpY->rLink = newNode;
        }
        else
        {
            pTmpY->lLink = newNode;
        }
        newNode->pLink = pTmpY;
    }
    newNode->lLink = &nil;
    newNode->rLink = &nil;
    newNode->corlor = RED;
    
    printf("%s(%d):root %d\n", __FILE__, __LINE__, (*root)->info);
    traverseTree(*root);
    printf("%s(%d):\n", __FILE__, __LINE__);
    rb_insert_fixup(root, newNode);
    printf("%s(%d):\n", __FILE__, __LINE__);

proc_over:
    return 0;
}

template<class elemType>
int rb_delete_fixup(rbNode<elemType> **root, rbNode<elemType> *delNode)
{
    rbNode<elemType> *pTmpX = delNode;
    while(pTmpX != *root && pTmpX->corlor == BLACK)
    {
        //cur node is the left child of parent
        if(pTmpX == pTmpX->pLink->lLink)
        {
            //brother node
            rbNode<elemType> *pTmpY = pTmpX->pLink->rLink;
            if(pTmpY != &nil && pTmpY->corlor == RED)
            {
                printf("delete fixup left case 1\n");
                //case 1
                pTmpY->corlor = BLACK;
                pTmpY->pLink->corlor = RED;
                if(*root == pTmpY->pLink)
                {
                    *root = pTmpY;
                }
                left_rotate(pTmpY->pLink);
                pTmpY = pTmpX->pLink->rLink;
            }
            if(pTmpY != &nil && pTmpY->lLink->corlor == BLACK 
                && pTmpY->rLink->corlor == BLACK)
            {
                printf("delete fixup left case 2\n");
                //case 2
                pTmpY->corlor = RED;
                pTmpX = pTmpX->pLink;
            }
            else if(pTmpY->lLink != &nil && pTmpY->rLink->corlor == BLACK)
            {
                printf("delete fixup left case 3\n");
                //case 3
                pTmpY->lLink->corlor = BLACK;
                pTmpY->corlor = RED;
                right_rotate(pTmpY);
                pTmpY = pTmpX->pLink->rLink;
            }
            else
            {
                printf("delete fixup left case 4\n");
                //case 4
                pTmpY->corlor = pTmpX->pLink->corlor;
                pTmpX->pLink->corlor = BLACK;
                pTmpY->rLink->corlor = BLACK;
                if(pTmpX->pLink == *root)
                {
                    *root = pTmpX;
                }
                left_rotate(pTmpX->pLink);
            }
        }
        else//cur node is the right child of parent
        {
            //brother node
            rbNode<elemType> *pTmpY = pTmpX->pLink->lLink;
            if(pTmpY != &nil && pTmpY->corlor == RED)
            {
                printf("delete fixup right case 1\n");
                //case 1
                pTmpY->corlor = BLACK;
                pTmpY->pLink->corlor = RED;
                if(*root == pTmpY->pLink)
                {
                    *root = pTmpY;
                }
                right_rotate(pTmpY->pLink);
                pTmpY = pTmpX->pLink->lLink;
            }
            if(pTmpY != &nil && pTmpY->lLink->corlor == BLACK 
                && pTmpY->rLink->corlor == BLACK)
            {
                printf("delete fixup right case 2\n");
                //case 2
                pTmpY->corlor = RED;
                pTmpX = pTmpX->pLink;
            }
            else if(pTmpY->rLink != &nil && pTmpY->lLink->corlor == BLACK)
            {
                printf("delete fixup right case 3\n");
                //case 3
                pTmpY->rLink->corlor = BLACK;
                pTmpY->corlor = RED;
                left_rotate(pTmpY);
                pTmpY = pTmpX->pLink->lLink;
            }
            else
            {
                printf("delete fixup right case 4\n");
                //case 4
                pTmpY->corlor = pTmpX->pLink->corlor;
                pTmpX->pLink->corlor = BLACK;
                pTmpY->lLink->corlor = BLACK;
                if(pTmpX->pLink == *root)
                {
                    *root = pTmpX;
                }
                right_rotate(pTmpX->pLink);
            }
        }
    }

    return 0;
}

template<class elemType>
int deleteNode(rbNode<elemType> **root, rbNode<elemType> *delNode)
{
    rbNode<elemType> *pY = NULL;
    rbNode<elemType> *pX = NULL;
    if(delNode->lLink == &nil || delNode->rLink == &nil)
    {
        pY = delNode;
    }
    else
    {
        pY = successorElem(delNode);
    }
    if(pY->lLink != &nil)
    {
        pX = pY->lLink;
    }
    else
    {
        pX = pY->rLink;
    }
    pX->pLink = pY->pLink;
    if(pY->pLink == &nil)
    {
        *root = pX;
    }
    else
    {
        if(pY = pY->pLink->lLink)
        {
            pY->pLink->lLink = pX;
        }
        else
        {
            pY->pLink->rLink = pX;
        }
    }
    printf("%s(%d): %d, %d, %d\n", __FILE__, __LINE__,
        delNode->info, pY->info, pX->info);
    if(pY != delNode)
    {
        delNode->info = pY->info;
    }
    if(pY->corlor == BLACK)
    {
        printf("%s(%d):enter fixup pY %d\n", __FILE__, __LINE__, delNode->info);
        rb_delete_fixup(root, pX);
    }
    printf("%s(%d): %d, %d\n", __FILE__, __LINE__, delNode->info, pX->info);

    return 0;
}

template<class elemType>
int traverseTree(rbNode<elemType> *root)
{
    if(root != &nil)
    {
        if(root->lLink != &nil)
        {
            traverseTree(root->lLink);
        }
        printf(" %d, parent %d, corlor %s\n", 
                root->info, root->pLink->info, root->corlor==0?"BLACK":"RED");
        if(root->rLink != &nil)
        {
            traverseTree(root->rLink);
        }
    }

    return 0;
}

int main()
{
    vector<int> A;
    A.resize(14);
    rbNode<int> *tree = &nil;
    A ={27, 17, 3, 16, 13, 10, 1, 5, 7, 12, 4, 8, 9, 0};
    for(auto entry:A)
    {
        cout << entry<<endl;
    }
    printf("**************************\n");
    for(auto entry:A)
    {
        rbNode<int> *newNode = new rbNode<int>;
        newNode->info = entry;
        newNode->lLink = &nil;
        newNode->rLink = &nil;
        newNode->pLink = &nil;
        newNode->corlor = RED;

        printf("begin**insert %d, root %d\n", newNode->info, tree->info);
        insertNode(&tree, newNode );
        printf("end**insert %d, root %d***********************\n", newNode->info, tree->info);
        traverseTree(tree);
        printf("**************************\n");
//        if(newNode->info == 3)
//            break;
    }
    traverseTree(tree);
    printf("**************************\n");
    rbNode<int> *delNode = NULL;
    delNode = findElem(tree, 3);
    if(delNode == NULL)
    {
        printf("do not find info %d\n", 3);
    }
    else
    {
        deleteNode(&tree, delNode);
    }
    printf("****** after delete 3, root %d********************\n", tree->info);
    traverseTree(tree);
    printf("**************************\n");

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值