/*-----------------------------------------------------------

RB-Tree的插入和删除操作的实现算法

参考资料:

1) <>

2) http://lxr.linux.no/linux/lib/rbtree.c

作者:http://www.cppblog.com/converse/

您可以自由的传播,修改这份代码,转载处请注明原作者

红黑树的几个性质:

1) 每个结点只有红和黑两种颜色

2) 根结点是黑色的

3)空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。

4) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的

5) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点

的数目相同

-------------------------------------------------------------*/

#include

#include

#include

typedef int key_t;

typedef int data_t;

typedef enum color_t

{

RED = 0,

BLACK = 1

}color_t;

typedef struct rb_node_t

{

struct rb_node_t *left, *right, *parent;

key_t key;

data_t data;

color_t color;

}rb_node_t;

/* forward declaration */

rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root);

rb_node_t* rb_search(key_t key, rb_node_t* root);

rb_node_t* rb_erase(key_t key, rb_node_t* root);

int main()

{

int i, count = 900000;

key_t key;

rb_node_t* root = NULL, *node = NULL;

srand(time(NULL));

for (i = 1; i < count; ++i)

{

key = rand() % count;

if ((root = rb_insert(key, i, root)))

{

printf("[i = %d] insert key %d success!\n", i, key);

}

else

{

printf("[i = %d] insert key %d error!\n", i, key);

exit(-1);

}

if ((node = rb_search(key, root)))

{

printf("[i = %d] search key %d success!\n", i, key);

}

else

{

printf("[i = %d] search key %d error!\n", i, key);

exit(-1);

}

if (!(i % 10))

{

if ((root = rb_erase(key, root)))

{

printf("[i = %d] erase key %d success\n", i, key);

}

else

{

printf("[i = %d] erase key %d error\n", i, key);

}

}

}

return 0;

}

static rb_node_t* rb_new_node(key_t key, data_t data)

{

rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t));

if (!node)

{

printf("malloc error!\n");

exit(-1);

}

node->key = key, node->data = data;

return node;

}

/*-----------------------------------------------------------

|   node           right

|   / \    ==>     / \

|   a  right     node  y

|       / \           / \

|       b  y         a   b

-----------------------------------------------------------*/

static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root)

{

rb_node_t* right = node->right;

if ((node->right = right->left))

{

right->left->parent = node;

}

right->left = node;

if ((right->parent = node->parent))

{

if (node == node->parent->right)

{

node->parent->right = right;

}

else

{

node->parent->left = right;

}

}

else

{

root = right;

}

node->parent = right;

return root;

}

/*-----------------------------------------------------------

|       node           left

|       / \            / \

|    left  y   ==>    a   node

|   / \               / \

|  a   b             b   y

-----------------------------------------------------------*/

static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root)

{

rb_node_t* left = node->left;

if ((node->left = left->right))

{

left->right->parent = node;

}

left->right = node;

if ((left->parent = node->parent))

{

if (node == node->parent->right)

{

node->parent->right = left;

}

else

{

node->parent->left = left;

}

}

else

{

root = left;

}

node->parent = left;

return root;

}

static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root)

{

rb_node_t *parent, *gparent, *uncle, *tmp;

while ((parent = node->parent) && parent->color == RED)

{

gparent = parent->parent;

if (parent == gparent->left)

{

uncle = gparent->right;

if (uncle && uncle->color == RED)

{

uncle->color = BLACK;

parent->color = BLACK;

gparent->color = RED;

node = gparent;

}

else

{

if (parent->right == node)

{

root = rb_rotate_left(parent, root);

tmp = parent;

parent = node;

node = tmp;

}

parent->color = BLACK;

gparent->color = RED;

root = rb_rotate_right(gparent, root);

}

}

else

{

uncle = gparent->left;

if (uncle && uncle->color == RED)

{

uncle->color = BLACK;

parent->color = BLACK;

gparent->color = RED;

node = gparent;

}

else

{

if (parent->left == node)

{

root = rb_rotate_right(parent, root);

tmp = parent;

parent = node;

node = tmp;

}

parent->color = BLACK;

gparent->color = RED;

root = rb_rotate_left(gparent, root);

}

}

}

root->color = BLACK;

return root;

}

static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root)

{

rb_node_t *other, *o_left, *o_right;

while ((!node || node->color == BLACK) && node != root)

{

if (parent->left == node)

{

other = parent->right;

if (other->color == RED)

{

other->color = BLACK;

parent->color = RED;

root = rb_rotate_left(parent, root);

other = parent->right;

}

if ((!other->left || other->left->color == BLACK) &&

(!other->right || other->right->color == BLACK))

{

other->color = RED;

node = parent;

parent = node->parent;

}

else

{

if (!other->right || other->right->color == BLACK)

{

if ((o_left = other->left))

{

o_left->color = BLACK;

}

other->color = RED;

root = rb_rotate_right(other, root);

other = parent->right;

}

other->color = parent->color;

parent->color = BLACK;

if (other->right)

{

other->right->color = BLACK;

}

root = rb_rotate_left(parent, root);

node = root;

break;

}

}

else

{

other = parent->left;

if (other->color == RED)

{

other->color = BLACK;

parent->color = RED;

root = rb_rotate_right(parent, root);

other = parent->left;

}

if ((!other->left || other->left->color == BLACK) &&

(!other->right || other->right->color == BLACK))

{

other->color = RED;

node = parent;

parent = node->parent;

}

else

{

if (!other->left || other->left->color == BLACK)

{

if ((o_right = other->right))

{

o_right->color = BLACK;

}

other->color = RED;

root = rb_rotate_left(other, root);

other = parent->left;

}

other->color = parent->color;

parent->color = BLACK;

if (other->left)

{

other->left->color = BLACK;

}

root = rb_rotate_right(parent, root);

node = root;

break;

}

}

}

if (node)

{

node->color = BLACK;

}

return root;

}

static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save)

{

rb_node_t *node = root, *parent = NULL;

int ret;

while (node)

{

parent = node;

ret = node->key - key;

if (0 < ret)

{

node = node->left;

}

else if (0 > ret)

{

node = node->right;

}

else

{

return node;

}

}

if (save)

{

*save = parent;

}

return NULL;

}

rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root)

{

rb_node_t *parent = NULL, *node;

parent = NULL;

if ((node = rb_search_auxiliary(key, root, &parent)))

{

return root;

}

node = rb_new_node(key, data);

node->parent = parent;

node->left = node->right = NULL;

node->color = RED;

if (parent)

{

if (parent->key > key)

{

parent->left = node;

}

else

{

parent->right = node;

}

}

else

{

root = node;

}

return rb_insert_rebalance(node, root);

}

rb_node_t* rb_search(key_t key, rb_node_t* root)

{

return rb_search_auxiliary(key, root, NULL);

}

rb_node_t* rb_erase(key_t key, rb_node_t *root)

{

rb_node_t *child, *parent, *old, *left, *node;

color_t color;

if (!(node = rb_search_auxiliary(key, root, NULL)))

{

printf("key %d is not exist!\n");

return root;

}

old = node;

if (node->left && node->right)

{

node = node->right;

while ((left = node->left) != NULL)

{

node = left;

}

child = node->right;

parent = node->parent;

color = node->color;

if (child)

{

child->parent = parent;

}

if (parent)

{

if (parent->left == node)

{

parent->left = child;

}

else

{

parent->right = child;

}

}

else

{

root = child;

}

if (node->parent == old)

{

parent = node;

}

node->parent = old->parent;

node->color = old->color;

node->right = old->right;

node->left = old->left;

if (old->parent)

{

if (old->parent->left == old)

{

old->parent->left = node;

}

else

{

old->parent->right = node;

}

}

else

{

root = node;

}

old->left->parent = node;

if (old->right)

{

old->right->parent = node;

}

}

else

{

if (!node->left)

{

child = node->right;

}

else if (!node->right)

{

child = node->left;

}

parent = node->parent;

color = node->color;

if (child)

{

child->parent = parent;

}

if (parent)

{

if (parent->left == node)

{

parent->left = child;

}

else

{

parent->right = child;

}

}

else

{

root = child;

}

}

free(old);

if (color == BLACK)

{

root = rb_erase_rebalance(child, parent, root);

}

return root;

}

PHP红黑源码,红黑树的实现源码(第二次修订版)相关推荐

  1. day063:红黑树、红黑规则

    目录 一.红黑树 1.什么是红黑树? 2.红黑树与平衡二叉树的区别 二.红黑规则 1.红黑规则有五点 2.红黑树添加节点 3. 添加节点的总结 一.红黑树 1.什么是红黑树? 红黑树(又称平衡二叉B树 ...

  2. 红黑二叉树的左旋右旋和变色

    小白解析红黑树的基本 什么是红黑树 变色 右旋 什么是右旋呢? 左旋 什么情况下会左旋 什么是红黑树 这就是一个简单的红黑二叉树 红黑二叉树有以下几条基本的规则: 1. 节点分为红色或者黑色. 2.根 ...

  3. java 二叉树特点_java学习笔记-二叉树、平衡二叉树(AVL)、红黑二叉树(十)

    各种树 标签:数据结构范畴 二叉树的定义: 二叉树是树形结构的一个重要类型. 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为 ...

  4. 详解c++---红黑二叉树的原理和实现

    目录标题 什么是红黑二叉树树 红黑树的性质 红黑树的效率分析 红黑树的准备工作 红黑树的insert函数 节点的调整 情况一 情况二 情况三 转换的实现 打印函数 find函数 检查函数 什么是红黑二 ...

  5. 遍历HashMap源码——红黑树原理、HashMap红黑树实现与反树型化(三)

    本章将是HashMap源码的最后一章,将介绍红黑树及其实现,HashMap的remove方法与反树型化.长文预警~~ 遍历HashMap源码--红黑树原理.HashMap红黑树实现与反树型化 什么是红 ...

  6. Android技术栈(五)HashMap(包括红黑树)与ArrayMap源码解析

    1 总览 本文会对 Android 中常用HashMap(有红黑树)和ArrayMap进行源码解析,其中 HashMap 源码来自 Android Framework API 28 (JDK=1.8) ...

  7. 红黑二叉树(附写的源码)

    简单讲一下B树B+树 这些树的作用,主要都体现于增删改查. 而为了性能的增强,从二叉树开始一步步进化,有了有序二叉树,然后到平衡二叉树,然后到了23树. 但23树依然不太优越. 假如有1w的数据,那么 ...

  8. 红黑树中nil结点_什么是红黑树?程序员面试必问!

    点击上方java小组,选择"置顶公众号" 优质文章,第一时间送达 当在10亿数据中只需要进行10几次比较就能查找到目标时,不禁感叹编程之魅力!人类之伟大呀! -- 学红黑树有感. ...

  9. 红黑树的红黑标志有什么用

    红黑树使用红黑二色进行"着色",目的是利用颜色值作为二叉树的平衡对称性的检查,只要插入的节点"着色"满足红黑二色的规定,最短路径与最长路径不会相差的太远,红黑树 ...

最新文章

  1. Android Intent hasExtra()方法的使用
  2. 【Java】排序算法 之 【快速排序】 总结
  3. linux alpine 提示'/bin/sh: rc-service: not found'解决方案
  4. 遍历查询ldap服务器用户
  5. OpenGL剪切平面和双面渲染
  6. LeetCode 312. 戳气球(Burst Balloons)
  7. 【Vue2.0】—Vue中的key有什么作用?(四)
  8. python进阶15变量作用域LEGB
  9. python(十一)接口开发、写日志、发邮件、python来发请求、手动添加环境变量...
  10. c4d序列号_(图文+视频)野分享:手把手教你免费获取Megascans所有资产并应用于C4D...
  11. git commit --amend 用法
  12. 截面数据 缺少行业风险
  13. android textview svg,Android中使用SVG与WebFont矢量图标
  14. HTML 提交表单,JQuery接收内容
  15. 计算机毕业设计ssm动漫交流与推荐分析系统633g7系统+程序+源码+lw+远程部署
  16. 湖北智禾网店指导:入门卖家一定要了解的淘宝宝贝发布规则及注意事项。
  17. 抖音一个老人和一个机器人歌曲_《抖音》多年以后有个可爱老头歌曲分享
  18. 一些简单的shell实例
  19. 数学不好,可以当程序员么?
  20. OA系统定制化,企业办公管理需求的新趋势

热门文章

  1. Flowable 数据库表结构 ACT_HI_IDENTITYLINK
  2. plsql 快捷键设置
  3. Spring boot + mybatis + oracle代码生成器
  4. RabbitMQ的5种队列_Work模式_入门试炼_第5篇
  5. 企业实战_12_MyCat水平扩展_分库分表
  6. IntelliJ IDEA 2019 安装lombok
  7. 系统架构设计师 - 项目管理 - 挣值管理
  8. SpringCloud整合nacos服务时无法发现服务
  9. JS中split对多个分隔符的处理
  10. oracle中prad函数_等保测评2.0:Oracle身份鉴别