插入结点用到了上一次BST的插入函数(做了一点添加),并且在此基础上增加了保持红黑性质的调整函数。

还是先看看插入函数:

void RBTreeInsert(RBTree &T, int k)
{//T->parent->color = BLACK;Node *y = NULL;Node *x = T;Node *z = new Node;z->key = k;z->lchild = z->parent = z->rchild = NULL;while(x != NULL){y = x;if(k < x->key)x = x->lchild;elsex = x->rchild;}z->parent = y;if(y == NULL){T = z;T->parent = NULL;T->parent->color = BLACK;}elseif(k < y->key)y->lchild = z;elsey->rchild = z;z->lchild = NULL;z->rchild = NULL;z->color = RED;RBInsertFixup(T, z);
}

和上一次的BST基本没区别,只是添加了对新加结点z的颜色和子节点的处理。

这里把z的颜色设置为红色,然后进行处理。

:考虑为何把z的颜色设置为红色?

:个人认为如果设置为黑色,则破坏了性质五,而性质五关于黑高度的问题,涉及到了整棵树,全局性难以把握,所以这里设置为红色,虽然破坏了性质4,然是相对破坏性质5来说,更容易恢复红黑性质。大家如果有不同的想法,也可以留言谈谈。

接下来,就是对整棵树的调整了。

答:考虑插入z结点后,破坏的哪几条红黑性质?

答:破坏了性质2和性质4.

5条红黑性质要熟记,我这里再贴出来:

1. 每个结点或是红色,或是是黑色。
2. 根结点是黑的。
3. 所有的叶结点(NULL)是黑色的。(NULL被视为一个哨兵结点,所有应该指向NULL的指针,都看成指向了NULL结点。)
4. 如果一个结点是红色的,则它的两个儿子节点都是黑色的。
5. 对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

所以我们要做的就是恢复性质2和性质4.

先来看看具体实现的代码(这里只贴出部分代码):

void RBInsertFixup(RBTree &T, Node *z)
{while(z->parent->color == RED){if(z->parent == z->parent->parent->lchild){Node *y = z->parent->parent->rchild;Case1 //if(y->color == RED){z->parent->color = BLACK;y->color = BLACK;z->parent->parent->color = RED;z = z->parent->parent;}else{// Case 2 //if(z == z->parent->rchild){z = z->parent;LeftRotate(T, z);}// Case 3 //z->parent->color = BLACK;z->parent->parent->color = RED;RightRotate(T, z->parent->parent);}}else{///}}T->color = BLACK;
}

分三种情况,在代码中已用Case 1, Case 2, Case 3标记出。

大致说下判断情况:

1.首先让一个指针y指向z的叔父结点(z是要删除的结点)。

2.如果y的颜色是红色,Case 1。则使z的父亲结点和叔父结点的颜色改为黑,z的祖父结点颜色改为红。然后让z转移到z的祖父结点。

3.当y的颜色是黑色时,

①.首先判断z是否是其父亲结点的右儿子,若是,则调整为左儿子(用旋转)。

②.其次使z的父亲结点颜色为黑,z的祖父结点颜色为红,并以z的祖父结点为轴右旋。

具体我还是在草稿纸上画出。。。(可怜买不起数码相机,只能用手机拍了。。。)

(弱弱的问一句,看见网上有很多朋友做的一些代码讲解图很给力,不知道大家有什么软件吗?求推荐。。。)

以下是插入的完整代码:

void RBInsertFixup(RBTree &T, Node *z)
{while(z->parent->color == RED){if(z->parent == z->parent->parent->lchild){Node *y = z->parent->parent->rchild;Case1 //if(y->color == RED){z->parent->color = BLACK;y->color = BLACK;z->parent->parent->color = RED;z = z->parent->parent;}else{// Case 2 //if(z == z->parent->rchild){z = z->parent;LeftRotate(T, z);}// Case 3 //z->parent->color = BLACK;z->parent->parent->color = RED;RightRotate(T, z->parent->parent);}}else{Node *y = z->parent->parent->lchild;if(y->color == RED){z->parent->color = BLACK;y->color = BLACK;z->parent->parent->color = RED;z = z->parent->parent;}else{if(z == z->parent->lchild){z = z->parent;RightRotate(T, z);}z->parent->color = BLACK;z->parent->parent->color = RED;LeftRotate(T, z->parent->parent);}}}T->color = BLACK;
}void RBTreeInsert(RBTree &T, int k)
{//T->parent->color = BLACK;Node *y = NULL;Node *x = T;Node *z = new Node;z->key = k;z->lchild = z->parent = z->rchild = NULL;while(x != NULL){y = x;if(k < x->key)x = x->lchild;elsex = x->rchild;}z->parent = y;if(y == NULL){T = z;T->parent = NULL;T->parent->color = BLACK;}elseif(k < y->key)y->lchild = z;elsey->rchild = z;z->lchild = NULL;z->rchild = NULL;z->color = RED;RBInsertFixup(T, z);
}

转载于:https://www.cnblogs.com/downtjs/p/3364275.html

《算法导论》学习总结 — 13. 第13章 红黑树(2)相关推荐

  1. 【算法导论学习笔记】第3章:函数的增长

    原创博客,转载请注明: http://www.cnblogs.com/wuwenyan/p/4982713.html  当算法的输入n非常大的时候,对于算法复杂度的分析就显得尤为重要,虽然有时我们能通 ...

  2. 二叉树的中序遍历非递归方法(算法导论第三版12.1-3)

    二叉树的中序遍历非递归方法(算法导论第三版12.1-3) 1⃣️用栈实现 template<typename T> void inorder_tree_walk_non_recursion ...

  3. 算法导论中C语言代码,算法导论-学习笔记与进度

    算法导论 阅读进度 第一部分 基础知识 第一章 计算中算法的角色 Done 1.1 算法 输入与输出 算法可以解决哪些问题 数据结构 技术 一些比较难的问题 1.2 作为一种技术的算法 效率 算法和其 ...

  4. 算法导论第三版第十一章11.1-4

    算法导论第三版第十一章11.1-4 我们希望在一个非常大的数组上,通过利用直接寻址的方式来实现一个字典.开始时,该数组中可能包含一些无用信息,但要堆整个数组进行初始化时不太实际的,因为该数组的规模太大 ...

  5. 【Java数据结构与算法】第十四章 红黑树

    第十四章 红黑树 文章目录 第十四章 红黑树 一.红黑树 1.介绍 2.插入结点 3.删除结点 4.与平衡二叉树的对比 一.红黑树 1.介绍 红黑树(Red Black Tree)是平衡二叉树的其中一 ...

  6. 算法导论学习笔记 第2章 算法基础

    本章介绍了一个贯穿本书的框架,后续的算法设计都是在这个框架中进行的. 本章通过插入排序和归并排序两种常见的算法来说明算法的过程及算法分析,在分析插入排序算法时,书中是用了循环不变式证明了算法的正确性, ...

  7. 算法导论第十三章 红黑树

    写在前面:这一章真的把我害惨了,之前至少尝试看过3遍,每次看之前都下定决定一定要把它拿下,可是由于内容较多,深度够深,以致于每次要不是中途有什么事放弃了就跳过了,要不是花时间太多仍然不能理解而放弃.这 ...

  8. 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)...

    2019独角兽企业重金招聘Python工程师标准>>> 问题描述:序列X={x1,x2,-,xn},Y={y1,y2,-,yn},当Z={z1,z2-,zn}是X的严格递增下标顺序( ...

  9. 【算法导论学习-012】n个数随机等概率的抽样m个

    算法法导论>P129页课后题5.3-7 suppose we want to create a random sample of the set {1,2,3,-,n}, thatis, an ...

  10. 算法导论读书笔记-第十九章-斐波那契堆

    算法导论第19章--斐波那契堆 可合并(最小)堆(mergeable min-heap) : 支持以下5种操作的一种数据结构, 其中每一个元素都有一个关键字: MAKE-HEAP(): 创建和返回一个 ...

最新文章

  1. Pytorch归一化方法讲解与实战:BatchNormalization、LayerNormalization、nn.BatchNorm1d和LayerNorm()和F.normalize()
  2. echo 和 var_dump
  3. BroadcastReceiver的思考(3)
  4. 关于Mysql5.7高版本group by新特性报错
  5. android开发出现的错误,android 开发 错误集锦
  6. 有哪些小而美的中小厂?
  7. SpringMVC配置文件中的各个组件
  8. 和尚挖井故事给程序员的启示
  9. 你心心念念的 GitHub手机版APP终于来咯
  10. graphQL入门分享
  11. 三星android10手势,三星全面屏手势终于来了!看着有点熟悉
  12. 笑出腹肌,程序员从不撒谎,但注释却会
  13. 旅行商问题(travelling salesman problem, TSP) 解题报告
  14. [转载]ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件...
  15. Webcam with JavaFX
  16. Linux命令行二:远程复制命令 scp
  17. ansible 自动化运维工具——ansible Ad-Hoc 使用
  18. upload-labs 全1-21关 附详细解析(文件上传漏洞)
  19. 微信扫码支付功能(2)---用户扫码支付成功,微信异步回调商户接口
  20. 滑动窗口:给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

热门文章

  1. 机器传奇:全球13位科学家和他们的机器人“孩子”
  2. 全球半导体产业迁移 中国的机遇与挑战
  3. 2021 年 6 月程序员工资统计,平均 15052 元
  4. 黑客解锁微信一键洗白、删好友、批量实名认证功能!38 名“海贼王”被判刑...
  5. 腾讯会议用户突破1亿,发布企业版最高支持2000人同时参会
  6. DTU详解解读 概念到功能应用
  7. 迁移不是云计算面临的唯一障碍
  8. 一张图看懂混合云数据同步一站式解决方案
  9. 数学分析高等代数考研试题荟萃[更新至2017年10月1日]
  10. 聊聊动画引擎 pop