高效实现红黑树的插入--c实现

原创 2016年08月30日 16:28:19

高效实现红黑树的插入

引言:
红黑树是一种特殊的二叉排序树,像java,c++的关联数组,如map都是用红黑树实现。
为什么红黑树应用比原生的二叉排序树(BST)和高度平衡二叉树(AVL)要更为广泛?
答:BST的深度不可控性,比如数据有序插入。不同形态的二叉排序树有不同的性能。
线性
图中a蜕化为线性链表,查找复杂度O(n),b图查找复杂度lg(n)。
而AVL插入、查找的时间复杂度都是lg(n),和红黑树相同。但是AVL是高度平衡的,插入删除更加容易引起不平衡,维护开销大。
所以红黑树是BST和AVL的这种选择,拥有插入,删除,查找的lg(n)时间复杂度。我个人理解,红黑树的查找性能肯定略逊于AVL,但这会在插入和删除开销上得到弥补,所有红黑树的统计性能最高。

红黑树的五个性质

  1. 每个结点要么是红的,要么是黑的。
  2. 根结点是黑的。
  3. 每个叶结点,即空结点(NIL)是黑的。
  4. 如果一个结点是红的,那么它的俩个儿子都是黑的。
  5. 对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

红黑树是主要通过性质五来约束树的高度,提高树的平衡性。因为从该结点到其子孙结点的所有路径上包含相同数目的黑结点,所以新插入的结点需要是红结点来保证黑节点数目相等。又通过性质四来维护树的平衡性。

红黑树的插入
红黑树示例
这里写图片描述

插入动画演示

动画演示红黑树的插入过程-点击观看

插入情况及解决方案:

  1. 空树
    方案:检测是否是根节点,如果是,将颜色改为黑

  2. 父亲节点p是黑色
    方案:不会破坏红黑树的性质,不需要改变

  3. 父节点P红色,祖父节点G黑色,叔节点U红色
    方案:祖父结点必然是黑色,不是已经不满足红黑树的性质了。
    将当前节点的父节点和叔叔节点涂黑,祖父结点涂红,把当前结点指向祖父节点(递归平衡,进入新的情况)

  4. 父节点P红色,祖父节点G黑色,叔节点U黑色,N左叶子
    方案:父节点变为黑色,祖父节点变为红色,在祖父节点为支点右旋
    (递归平衡,进入新的情况)

  5. 父节点P红色,祖父节点G黑色,叔节点U黑色,N右叶子
    方案:以新当前节点的父节点左旋,当前节点的父节点做为新的当前节点(递归平衡,进入新的情况)

建议参考优秀博客,对入插入情况非常详细点这里查看
配合上面的红黑树的插入视频,把几种情况弄懂非常容易。

附上c的源码,希望对您有些帮助,核心代码不过20行。

/*2016-8-30 hiluo-scu*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node* link;
link null=NULL;
struct node {
    int item;
    link l;
    link r;
    int red;
};

link NODE(int item,link l,link r,int red)
{
    link t = (link)malloc(sizeof(struct node));
    t->item = item;
    t->l = l;
    t->r = r;
    t->red = red;
    return t;
}

//初始化简历哨兵结点(叶节点或NULL结点)
link RB_init()
{
    null = NODE(0,NULL,NULL,0);
    null->l = null;null->r=null;
    return null;
}

//线序遍历
void pprintf(link t)
{
    if(t!=null)
    {
        printf("%d%c \n",t->item,t->red?'+':' ');
        pprintf(t->l);
        pprintf(t->r);
    }
}
//中序遍历
void IN_pprintf(link t)
{
    if(t!=null)
    {
        IN_pprintf(t->l);
        printf("%d%c \n",t->item,t->red?'+':' ');
        IN_pprintf(t->r);
    }
}

link rotR(link t)
{
    link x = t->l;t->l = x->r; x->r = t;
    return x;
}

link rotL(link t)
{
    link x = t->r;t->r = x->l; x->l = t;
    return x;
}

//核心代码 高效地实现红黑树插入
link insert_node(link t,int item,int sw)
{
    if(t==null) return NODE(item,null,null,1);
    if( (t->l->red==1) && (t->r->red==1) )
    {
        t->red = 1;
        t->l->red = 0;
        t->r->red = 0;
    }
    if(item < t->item)
    {
        t->l = insert_node(t->l,item,0);
        if(t->red && t->l->red &&sw) t=rotR(t);
        if(t->l->red && t->l->l->red)
        {
            t=rotR(t);t->red = 0;t->r->red = 1;
        }
    }else{
        t->r = insert_node(t->r,item,1);
        if(t->red && t->r->red && !sw) t=rotL(t);
        if(t->r->red && t->r->r->red)
        {
            t=rotL(t);
            t->red = 0;
            t->l->red = 1;
        }
    }
    return t;
}

link RB_insert(link root,int item)
{
    root = insert_node(root,item,0);
    root->red = 0;
    return root;
}
/*2016-8-30 hiluo-scu*/
int main()
{
    int N = 14;
    int a[]={10,85,15,70,20,60,30,50,65,80,90,40,5,55};
    //srand(time(NULL));
    link root = RB_init();
    for(int i=0;i<N;i++)
    {
        root = RB_insert(root,a[i]);
    }
    printf("\t---线序遍历tree------(+表示红色结点)\n");
    pprintf(root);
    printf("\t---中序遍历tree------(+表示红色结点)\n");
    IN_pprintf(root);
    return 0;
}

参考博客:
http://blog.csdn.net/v_JULY_v/article/details/6105630
http://blog.csdn.net/eric491179912/article/details/6179908
感谢!

版权声明:本文为博主原创文章,未经博主允许不得转载。

经典算法:红黑树的C语言实现 ( 插入 、删除 )

红黑树这个东西可以说是传说中的“牛刀”了,一般的小场合是用不上滴,但是我觉得还是很重要,所以花了将近三天,对照着算法导论,把红黑树给实现出来了,有关红黑树的资料很多,大家可以在网上先搜一下,最好是能亲...
  • fantasywindy
  • fantasywindy
  • 2010年07月21日 14:06
  • 5546

算法导论学习---红黑树详解之插入(C语言实现)

前面我们学习二叉搜索树的时候发现在一些情况下其高度不是很均匀,甚至有时候会退化成一条长链,所以我们引用一些”平衡”的二叉搜索树。红黑树就是一种”平衡”的二叉搜索树,它通过在每个结点附加颜色位和路径上的...
  • acm_lkl
  • acm_lkl
  • 2015年07月05日 11:18
  • 1080

红黑树-JAVA实现(红黑树插入和删除)

红黑树介绍 红黑树是平衡二叉查找树的一种。平衡树在插入和删除的时候,会通过旋转操作将高度保持在logN。其中两款具有代表性的平衡树分别为AVL树和红黑树。AVL树由于实现比较复杂,而且插入和删除性能差...
  • Tcorpion
  • Tcorpion
  • 2017年02月10日 12:41
  • 1691

红黑树(附完整C代码)

版权声明:原创不易,转载请注明转自weewqrer 红黑树红黑树简介首先红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是RED或者BLACK。通过对一条从根节点到NIL叶...
  • weewqrer
  • weewqrer
  • 2016年07月09日 14:06
  • 6069

红黑树-C语言实现

红黑树的c语言实现。
  • binwin20
  • binwin20
  • 2013年12月09日 13:04
  • 2458

红黑树插入删除操作

R-B Tree简介     R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(...
  • justdoithai
  • justdoithai
  • 2016年09月26日 15:42
  • 414

【算法导论】红黑树详解之一(插入)

红黑树是建立在二叉查找树的基础之上的,关于二叉查找树可以参看【算法导论】二叉搜索树的插入和删除和【算法导论】二叉树的前中后序非递归遍历实现。对于高度为h的二叉查找树而言,它的SEARCH、INSERT...
  • cyp331203
  • cyp331203
  • 2015年01月14日 11:11
  • 3599

TreeMap实现原理 红黑树

TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做:根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致...
  • a616413086
  • a616413086
  • 2016年09月19日 15:10
  • 2524

算法导论——红黑树插入算法C++实现

红黑树图文详解及其C++语言实现
  • xiaowang627
  • xiaowang627
  • 2016年05月07日 23:51
  • 3003

用c++实现红黑树的判断、插入、遍历操作

红黑树        红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路...
  • yanxiaolx
  • yanxiaolx
  • 2016年07月26日 22:13
  • 2018
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高效实现红黑树的插入--c实现
举报原因:
原因补充:

(最多只允许输入30个字)