STL源码剖析 - RB-tree
在我看来,看源码是一件既痛苦又兴奋的事。当我们在推敲其中的难点时,是及其痛苦的,但当发现实现代码是那么丝滑简洁时,“wc, nb!”。
1. 导语
如果我们去看关联式容器map、set、multimap、multiset源代码,我们发现绝大部分操作如插入、修改、删除、搜索,均是由其内含的红黑树来完成的,我们有必要去揭开她的神秘面纱,一览她的绝世风姿。
(如果你手头还没有《STL源码剖析》时,强烈建议你现在就去买一本or文末的百度云链接or网路上的其他资源)
关键词:RB-tree、BST、AVL tree 、STL Sources
从哪里讲起呢?
二叉搜索树,每个节点最多有两个子节点,而每个节点键值一定大于左子树键值节点键值,而小于右子树节点键值。这样一来,就可以提供对数时间的插入和搜索。
当然,较为复杂的是它的删除操作。
1.如果删除的是叶子,那么直接删除delete该指针即可;
2. 如果删除的不是叶子,而他只有一个节点,那么就将其子节点连至它的父节点;
3. 如果删除的不是叶子,而他有两个节点,那么就用它的右子树的最小节点代替他(值赋给它),删除该右子树最小节点。
(这是为什么?因为删除之后还要保证二叉树的搜索,所以替代他的元素就需要是比他大的下一个元素,而比他大的元素都在右子树,且最小的哪一个就是最左边的那一个。其实在二叉搜索树中,要找最大就一直向右子树找,要找最小就一直往左子树找)
上述例子是在二叉树平衡的情况下进行的。平衡即左右子树高度相近,完全平衡则要求左右子树高度(深度/层数)完全相等。要是完全平衡的条件下,我们的搜索和插入操作就会是对数时间,这无疑是相当快的(当然比起Hashtable的大致O(1)来说是较慢的),这在关联式容器中是我们所追求的。因为它们的底层均不是线性结构,能达到常数时间的查找/搜索。
但是要知道,维护一个二叉树的完全平衡是非常耗时的,比如我插入之后,很大概率就会使得二叉树不完全平衡,就需要复杂度旋转移位操作,这对于插入来说非常不划算,也就是说,我们没必要为了平衡而平衡,只要达到大致平衡,就可以得到统计上的对数查找插入时间。
那么进入我们的正题,平衡二叉搜索树。
2. 平衡二叉搜索树
这里的平衡,是指没有任何节点的深度过大,而非绝对的平衡。
代表结构:RB-tree、AVL-tree、AA-tree
本片主要介绍红黑树,AVL-tree将在其他篇章中讲解。
3. RB-tree
红黑树,一种自平衡的二叉查找树。它的最坏情况运行时间也是良好的,并且在实践中是高效的,它可以在O(log n)时间内做查找,插入和删除。(来自百度百科)
无疑,它的实现是非常复杂的,搜索几乎是是它最为简单的操作,复杂度O(log n),最坏也是如此。而插入和删除就比较困难了,查找到插入节点/删除节点复杂度O(log n),在插入时、插入后、删除后都需要满足它的红黑规则限定
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ... 原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ... STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ... 读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ... 首先,去侯捷网站下载相关文档:http://jjhou.boolan.com/jjwbooks-tass.htm. 这本书采用的是Cygnus C++ 2.91 for windows.下载地址:ht ... STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ... 1 STL迭代器原理 1.1 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ... 原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ... 最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ... 红色部分 定义model 定义api接口 Service 主要分为这几步 定义feignClient 打开cms接口,根据接口来写feignClient Service调用 service调用feig ... 3.3.4.4 解决swagger-ui无法访问 当课程管理加了授权之后再访问swagger-ui则报错: 这里默认配置的了所有的请求都必须认证 把图片认证的路径加进去的话 那么访问课程图片的列表 就 ... NULL就是0 nullptr是空指针[c++11] zookeeper的配置 日志自动清理这两个参数都是在zoo.cfg中配置的: autopurge.purgeInterval 这个参数指定了清理频率,单位是小时,需要填写一个1或更大的整数,默 ... # 配置ueditor上传文件到七牛UEDITOR_UPLOAD_TO_QINIU = True # 设置为True是,视为开始把图片传到七牛储存,本地不储存UEDITOR_QINIU_ACCESS_ ... Centos 7 端口和防火墙命令: 查看已经开放的端口:firewall-cmd --list-ports 开启端口:firewall-cmd --zone=public --add-port=80 ... 因为有画UML图的需求,所以得在电脑上安装Rational Rose.开始准备安装Rational Rose 2003,但是破解过程过于繁琐而且似乎一直遇到各种问题,就决定安装Rational Ros ... 画阴影: CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(contex ... 教程总体概括:Mac OS X系统简介:C语言:OC语言:Foundation:iOS开发:项目实战. 3.第一个c语言程序#include <stdio.h>//预处理指令:在编译之前执 ... 一.问题阐述 用URL传参数的时候,用&符号连接,如果某一个参数中含"#$ ^ & * + ="这些符号的时候,在另一个页面getParameter就会取不到传过来 ...STL源码剖析 - RB-tree的更多相关文章
随机推荐