红黑树详细介绍三

        根据之前红黑树的原理和《算法导论》上面的伪代码,我用代码将增加和调整的代码实现了一下,如有不对请大家指正。代码可以结合前两篇文章看。

        这次把剩下的删除结加上了,经过测试是可以使用的。

红黑树的详细介绍一

红黑树详细介绍二

/*
 * =====================================================================================
 *
 *       Filename:  rbtree->h
 *
 *    Description:  red black tree
 *
 *        Version:  1->0
 *        Created:  2014年05月05日 08时48分50秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  我叫程序猿XXX  
 *        Company:  
 *
 * =====================================================================================
 */
#ifndef __RBTREE__H
#define __RBTREE__H

#define bool int
#define successed 0
#define failed -1
#define BLACK 0
#define RED 1

typedef struct _rbtree_node{
        struct _rbtree_node *p; 
        struct _rbtree_node *left;
        struct _rbtree_node *right;
        int key;
        int color;
}*p_rbtree_node;


struct _rbtree_node node;

p_rbtree_node getNode(p_rbtree_node x); 
bool leftRotate(p_rbtree_node *root, p_rbtree_node x); 
bool rightRotate(p_rbtree_node *root, p_rbtree_node x);
bool rbInert(p_rbtree_node *root, p_rbtree_node z);
bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z);
bool rbBuilt(void);
bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v);
bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x);
p_rbtree_node Delete(p_rbtree_node z);
p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z);
p_rbtree_node treeMinimum(p_rbtree_node z);
p_rbtree_node Search(int key);
p_rbtree_node priSearch(p_rbtree_node *root, int key);
void rbDisplay(p_rbtree_node *root);
void Display(void);

#endif



rbtree.c

/*
 * =====================================================================================
 *
 *       Filename:  rbtree.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年05月05日 09时01分00秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  我叫程序猿XXX 
 *        Company:  
 *
 * =====================================================================================
 */
#include "rbtree.h"
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
p_rbtree_node nil = &node;
p_rbtree_node root;

p_rbtree_node getNode(p_rbtree_node x)
{
        x = NULL;
        x = (p_rbtree_node)malloc(sizeof(struct _rbtree_node));
        if (x == NULL)
        {
                return NULL;
        }
        memset(x, 0, sizeof(struct _rbtree_node));

        return x;
}

bool leftRotate(p_rbtree_node *root, p_rbtree_node x)
{
        p_rbtree_node y = NULL;
        y = x->right;   //set y
        x->right = y->left;
        if (y->left !=  nil)
                y->left->p = x;
        y->p = x->p;
        if (x->p == nil)
                *root = y;
        else if (x == x->p->left)
                x->p->left = y;
        else
                x->p->right = y;
        y->left = x;
        x->p = y;

        return successed;
}

bool rightRotate(p_rbtree_node *root, p_rbtree_node x)
{
        p_rbtree_node y = NULL;
        y = x->left;
        x->left = y->right;
        if (y->right != nil)
                y->right->p = x;
        y->p = x->p;
        if (x->p == nil)
                *root = y;
        else if (x == x->p->left)
                x->p->left = y;
        else
                x->p->right = y;
        y->right = x;
        x->p = y;

        return successed;
}

bool rbInsert(p_rbtree_node *root, p_rbtree_node z)
{
        p_rbtree_node y = nil;
        p_rbtree_node x = *root;
        while (x != nil)
        {
                y = x;
                if (z->key < x->key)
                        x = x->left;
                else
                        x = x->right;
        }
        z->p = y;
        if (y == nil)
        {
                *root = z;
        }
        else if (z->key < y->key)
                y->left = z;
        else
                y->right = z;
        z->left = nil;
        z->right = nil;
        z->color = RED;
        rbInsertFixup(root, z);

        return successed;
}

bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z)
{
        while (z->p->color == RED)
        {
                p_rbtree_node y = NULL;
                if (z->p == z->p->p->left)
                {
                        y = z->p->p->right;
                        if (y->color == RED)
                        {
                                z->p->color = BLACK;
                                y->color = BLACK;
                                z->p->p->color = RED;
                                z = z->p->p;
                        }
                        else if (z == z->p->right)
                        {
                                z = z->p;
                                leftRotate(root, z);
                        }
                        else
                        {
                                z->p->color = BLACK;
                                z->p->p->color = RED;
                                rightRotate(root, z->p->p);
                        }
                }
                else
                {
                        y = z->p->p->left;
                        if (y->color == RED)
                        {
                                z->p->color = BLACK;
                                y->color = BLACK;
                                z->p->p->color = RED;
                                z = z->p->p;
                        }
                        else if (z == z->p->left)
                        {
                                z = z->p;
                                rightRotate(root, z);
                        }
                        else
                        {
                                z->p->color = BLACK;
                                z->p->p->color = RED;
                                leftRotate(root, z->p->p);
                        }
                }
        }
        (*root)->color = BLACK;
        return successed;
}

bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v)
{
        if (u->p == nil)
        {
                *root = v;
        }
        else if (u == u->p->left)
        {
                u->p->left = v;
        }
        else
                u->p->right = v;
        v->p = u->p;
        return successed;
}

p_rbtree_node treeMinimum(p_rbtree_node z)
{
        while (z->left != nil)
                z = z->left;
        return z;
}

bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x)
{
        p_rbtree_node w = nil;
        while (x != nil && x->color == BLACK)
        {
                if (x == x->p->left)
                {
                        w = x->p->right;
                        if (w->color == RED)
                        {
                                w->color = BLACK;
                                x->p->color = RED;
                                leftRotate(root, x->p);
                                w = x->p->right;
                        }
                        else if (w->right->color == BLACK && w->left->color == BLACK)
                        {
                                w->color = RED;
                                x = x->p;
                        }
                        else if (w->right->color == BLACK)
                        {
                                w->left->color = BLACK;
                                w->color = RED;
                                rightRotate(root, w);
                                w = x->p->right;
                        }
                        else
                        {
                                w->right->color = BLACK;
                                w->color = x->p->color;
                                w->p->color = BLACK;
                                leftRotate(root, x->p);
                                x = nil;
                        }
                }
                else
                {
                        w = x->p->left;
                        if (w->color == RED)
                        {
                                w->color = BLACK;
                                x->p->color = RED;
                                rightRotate(root, x->p);
                                w = x->p->left;
                        }
                        else if (w->left->color == BLACK && w->right->color == BLACK)
                        {
                                w->color = RED;
                                x = x->p;
                        }
                        else if (w->left->color == BLACK)
                        {
                                w->color = RED;
                                w->right->color = BLACK;
                                leftRotate(root, w);
                                w = x->p->left;
                        }
                        else
                        {
                                w->color = RED;
                                w->left->color = BLACK;
                                w->p->color = BLACK;
                                rightRotate(root, x->p);
                                x = nil;
                        }
                }
        }
        x->color = BLACK;
}

p_rbtree_node Delete(p_rbtree_node z)
{
        return rbDelete(&root, z);
}

p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z)
{
        p_rbtree_node y = nil, x = nil;
        y = z;
        int y_original_color = y->color;
        if (z->left == nil)
        {
                x = z->right;
                rbTransplant(root, z, x);

        }
        else if (z->right == nil)
        {
                x = z->left;
                rbTransplant(root, z, x);
        }
        else
        {
                y = treeMinimum(z->right);
                y_original_color = y->color;
                x = y->right;
                if (y->p == z)
                {
                        x->p = y;
                }
                else
                {
                        rbTransplant(root, y, x);
                        y->right = z->right;
                        z->right->p = y;
                }
                rbTransplant(root, z, y);
                y->left = z->left;
                y->left->p = y;
                y->color = z->color;
        }
        if (y_original_color == BLACK)
                rbDeleteFixup(root, x);
        return z;
}

bool rbBuilt()
{
        node.p = NULL;
        node.left = NULL;
        node.right = NULL;
        node.key = -1;
        node.color = BLACK;
        root = nil;
        p_rbtree_node n1 = getNode(n1);
        n1->key = 1;
        rbInsert(&root, n1);

        p_rbtree_node n2 = getNode(n2);
        n2->key = 2;
        rbInsert(&root, n2);

        p_rbtree_node n4 = getNode(n4);
        n4->key = 4;
        rbInsert(&root, n4);

        p_rbtree_node n5 = getNode(n5);
        n5->key = 5;
        rbInsert(&root, n5);

        p_rbtree_node n7 = getNode(n7);
        n7->key = 7;
        rbInsert(&root, n7);

        p_rbtree_node n8 = getNode(n8);
        n8->key = 8;
        rbInsert(&root, n8);

        p_rbtree_node n11 = getNode(n11);
        n11->key = 11;
        rbInsert(&root, n11);

        p_rbtree_node n14 = getNode(n14);
        n14->key = 14;
        rbInsert(&root, n14);

        p_rbtree_node n15 = getNode(n15);
        n15->key = 15;
        rbInsert(&root, n15);

        return successed;
}

void rbDisplay(p_rbtree_node *root)
{
        if (*root == nil)
                return;
        rbDisplay(&((*root)->left));
        if ((*root)->color == RED)
                printf("key=%d, color=RED\n", (*root)->key);
        else
                printf("key=%d, color=BLACK\n", (*root)->key);
        rbDisplay(&((*root)->right));
}

void rbMidDisplay(p_rbtree_node *root)
{
        if (*root == nil)
                return;
        if ((*root)->color == RED)
                printf("key=%d, color=RED\n", (*root)->key);
        else
                printf("key=%d, color=BLACK\n", (*root)->key);
        rbMidDisplay(&((*root)->left));
        rbMidDisplay(&((*root)->right));
}

void Display(void)
{
        rbDisplay(&root);
        rbMidDisplay(&root);
}


test.c 测试文件

*
 * =====================================================================================
 *
 *       Filename:  test.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年05月05日 11时34分19秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  我叫程序猿XXX  
 *        Company:  
 *
 * =====================================================================================
 */
#include "rbtree.h"
#include <stdio.h>

int main(void)
{
        rbBuilt();
        Display();
        int key = 5;
        p_rbtree_node node = Search(5);
        p_rbtree_node temp = NULL;
        temp = Delete(node);
        printf("*******temp->key = %d**********\n", temp->key);
        Display();
    
        return 0;
}


    代码的运行截图如下:

    代码是通过先序和中序遍历得出的结果。

添加删除之后的运行结果如下:


    我的编译系统是Linux,编译环境是gcc 版本 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC) 。后面将删除代码添加上。如果代码中有任何不对的地方,请大家指出,我好及时修改,谢谢大家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为你提供更详细的关于红黑树介绍红黑树是一种自平衡的二叉查找树,它在插入和删除节点时能够保持树的平衡,从而保证了树的高度较低,使得查找、插入和删除操作的时间复杂度能够保持在O(log n)。 红黑树的特点如下: 1. 每个节点要么是红色,要么是黑色。 2. 根节点是黑色的。 3. 所有叶子节点(NIL节点)都是黑色的。 4. 如果一个节点是红色的,则它的两个子节点都是黑色的。 5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 通过这些特点,红黑树能够保持以下性质: 1. 从根节点到叶子节点的最长路径不会超过最短路径的两倍长。这保证了红黑树的高度始终保持在O(log n)。 2. 每个红色节点的两个子节点都是黑色的,这意味着没有两个连续的红色节点。这个性质保证了红黑树不会出现路径中连续的红色节点,从而避免了最坏情况下的不平衡。 红黑树的插入和删除操作都需要进行特定的调整来保持树的平衡。在进行插入操作时,首先将新节点插入到二叉查找树中,并将其标记为红色。然后,根据红黑树的特性进行调整,例如通过变色、左旋、右旋等操作来保持平衡。删除操作也需要进行类似的调整过程。 红黑树广泛应用于许多编程语言中的数据结构实现,例如C++中的std::map和std::set,Java中的TreeMap和TreeSet等。 希望这次更详细介绍对你有帮助!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值