红黑树

动画 | 什么是红黑树?(与2-3树等价)

自古美人都是妖i 提交于 2020-01-26 15:09:34
学习过2-3树之后就知道应怎样去理解红黑树了,如果直接看「算法导论」里的红黑树的性质,是看不出所以然。我们也看看一颗二分搜索树满足红黑的性质: 1.每个节点或是红色的,或是黑色的; 2.根节点是黑色的; 3.每个叶子节点(NIL)是黑色的; 4.如果一个节点是红色的,则它的两个子节点都是黑色的; 5.对每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。 如果说前面4个还算理解,那第5个性质又是怎么去理解呢?此时我们借着2-3树去理解基本的红黑树,当然我会在后几篇文章介绍2-3-4树以及基于2-3-4树的红黑树。 抛开上面二分搜索树满足红黑的性质,我们知道2-3树不是二叉树,我们把它转换成一颗二叉树,2-节点很好转,3-节点转二叉却有两种,如下图: 红黑是指被指向节点的链接颜色,对于一颗2-3树,因为3-节点的存在有很多不同的二叉树的表示,所以我们只考虑左倾的情况。 左倾红黑树和2-3树等价的定义 红黑树的定义是含有红黑链接并满足下列条件的二分搜索树: 1.红链接均为左连接; 2.没有任何一个节点同时和两条红链接相连; 3.该树是完美黑色平衡的,即任意空链接到根节点的路径上的黑链接数量相同(和2-3树等价的,任意节点到其叶子节点的高度都是相同的)。 因为2-3树不存在永久的4-节点,4-节点终归要分解的(在2-3-4树中,为了更好地插入和删除,4

红黑树性质与变换规则

a 夏天 提交于 2020-01-26 10:12:53
红黑树:平衡二叉树 jdk1.8 HashMap:数组+链表+红黑树 (处理Hash冲突) 时间复杂度:树的深度:logn 红黑树性质: 1.每个节点不是红色就是黑色 2.不可能有连在一起的红色节点(两个黑色节点可以连在一起) 3.根节点(入度为0)都是黑色root 4.每个红色节点的两个子节点都是黑色。 5.叶子节点(出度为0)都是黑色 为满足红黑树性质,红黑树有三种变换: 1.变颜色 2.左旋 3.右旋 变换规则: 1:当前节点的父亲是红色,且它的祖父节点的另一个子节点(叔叔节点)也是红色: 步骤: (1)把父节点设为黑色 (2)把叔叔节点也设为黑色 (3)把祖父节点(父亲的父亲节点(爷爷节点))设为红色 (4)把指针定义到祖父节点设为当前要操作的分析的点变换规则 2.左旋:当前父节点是红色,叔叔节点是黑色的时候,且当前的节点是右子树。 ——>左旋:以 父节点 作为根节点 左旋 3.右旋:当前父节点是红色,叔叔节点是黑色的时候,且当前的节点是左子数。 ——>右旋:以 祖父节点 作为根节点 右旋 颜色变换步骤: (1)把父节点变为黑色 (2)把祖父节点变为红色 基本代码展示: public class RedBlackTree { private final int R = 0 ; private final int B = 1 ; private Node root =

Nginx学习笔记 ---高级数据结构

寵の児 提交于 2020-01-26 03:15:31
动态数组 ngx_array_t 表示一块连续的内存,其中存放着数组元素,概念上和原始数组很接近 // 定义在 core/ngx_array.h typedef struct { void * elts ; // 数组的内存位置,即数组首地址 ngx_uint_t nelts ; // 数组当前的元素数量 size_t size ; // 数组元素的大小 ngx_uint_t nalloc ; // 数组可容纳的最多元素容量 ngx_pool_t * pool ; // 数组可使用的内存池 } ngx_array_t ; elts 就是原始的数组,定义成 void*,使用时应强转成相应的类型 nelts 相当于 vector.size(); size 相当于 sizeof(T); nalloc 相当于 vector.capacity(); pool 数组使用的内存池,相当于 vector 的 allocator 数组里的元素不断增加,当 nelts > nalloc 时将引起数组扩容,ngx_array_t 会向内存池 pool 申请一块两倍原大小的空间————这个策略和 std::vector 是一样的 但 ngx_array_t 扩容成本太高,它需要重新分配内存并且将数据拷贝,所以最好一次性分配足够的空间,避免动态扩容 操作函数: 使用 ngx_array_t.elts

对比分析HashMap、LinkedHashMap、TreeMap

杀马特。学长 韩版系。学妹 提交于 2020-01-26 01:05:23
前面花了4章对HashMap、LinkedHashMap以及TreeMap的原理实现进行了讲解,本章对它们进行简单的对比分析。 这里简单提一下,为什么前面没有单独一章来讲HashTable,HashTable是基于陈旧的Dictionary来实现的,效率上比起HashMap差很多,同时其唯一的优势“线程安全”的实现机制效率也是非常差的,现在一般都用ConcurrentHashMap,所以这个类基本上已经算是废弃了。 下面通过一个表格从各方面对比分析HashMap、LinkedHashMap、TreeMap HashMap LinkedHashMap TreeMap 原理 HashMap扩容机制及存取原理 LinkedHashMap如何保证顺序性 TreeMap原理实现及常用方法 线程安全 否 否 否 初始容量 16 16 0 存储结构 数组+链表/红黑树 数组+链表/红黑树,HashMap子类 红黑树 顺序规则 取值无顺序 取值按插入的顺序/按修改的顺序,根据accessOrder控制 插入时按key的自然顺序或者自定义顺序 存储特点 最多一条记录的key为null,可以多条记录value为null 最多一条记录的key为null,可以多条记录value为null 当为key的自然顺序存储时key不能为null,当自定义顺序时,通过传入的Comparator的实现控制 插入效率 高

HashMap-学习笔记

こ雲淡風輕ζ 提交于 2020-01-25 21:48:43
1.HashMap的特性 HashMap存储键值对(key : value) 实现快速存取,key跟value都允许为null,key只能有1个null 非线程安全 不能保证有序 2.HashMap的结构(jdk1.8) HashMap采用数组 + 链表或红黑树,节点是用Node 3.HashMap的put方法执行过程 先对key执行hash方法运算 (注意当key为null的时候,hash方法会固定返回0,根据hash & (length -1)的算法判定存入的数据会保存在数组[0] 的位置) static final int hash ( Object key ) { int h ; return ( key == null ) ? 0 : ( h = key . hashCode ( ) ) ^ ( h >>> 16 ) ; } 如果散列列表为空的时候,即第一次执行put方法,会调用resize()生成一个长度为16的Node数组 newCap = DEFAULT_INITIAL_CAPACITY ; //数组默认的初始长度16 newThr = ( int ) ( DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY ) ; //扩容阈值 加载因子0.75*16 Node < K , V > [ ] newTab = ( Node <

面试-集合

二次信任 提交于 2020-01-25 08:39:35
一、请说明List、Map、Set三个接口存取元素时,各有什么特点? 答:①List以特定索引来存取元素,可以有重复元素。 ②Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。 ③Map保存键值对映射,映射关系可以是一对一或者是多对一。 Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键构成排序树从而达到排序和去重的效果。 二、阐述ArrayList、Vector、LinkedLIst的存储性能和特性。 答:ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上比较ArrayList差,因为已经是java中的遗留容器。 LinkedList使用的是双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 Vector属于遗留容器,已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的

动画 | 什么是红黑树?(与2-3-4树等价)

混江龙づ霸主 提交于 2020-01-24 19:50:44
二分搜索树是为了快速查找而生,它是一颗二叉树,每一个节点只有一个元素(值或键值对),左子树所有节点的值均小于父节点的值,右子树所有的值均大于父节点的值,左右子树也是一颗二分搜索树,而且没有键值相等的节点。它的查找、插入和删除的时间复杂度都与树高成比例,期望值是O(log n)。 但是插入数组如[],二分搜索树的缺点就暴露出来了,二分搜索树退化成线性表,查找的时间复杂度达到最坏时间复杂度O(n)。 动画:二分搜索树退化成线性表 那有没有插入和删除操作都能保持树的完美平衡性(任何一个节点到其叶子节点的路径长度都是相等的)? 有,B树。B树是一种自平衡的树,根节点到其叶子节点的路径高度都是一样的,能够保持数据有序(通过中序遍历能得到有序数据)。B树一个节点可以拥有2个以上的子树,如2-3树、2-3-4树甚至2-3-4-5-6-7-8树,它们满足二分搜索树的性质,但它们不属于二叉树,也不属于二分搜索树。 2-3-4树的完美平衡,每条从根节点到叶子节点的路径的高度都是一样的 2-3-4树有以下节点组成: 2-节点,含有一个元素(值或键值对)和两个子树(左右子树),左子树所有的值均小于父节点的值,右子树所有的值均大于父节点的值; 3-节点,含有两个元素和三个子树,左子树所有的值均小于父节点最小元素的值,中间子树所有的值均位于父节点两个元素之间,右子树所有的值均大于父节点最大元素的值; 4-节点

红黑树的插入过程

穿精又带淫゛_ 提交于 2020-01-24 16:42:38
红黑树是一种自平衡的二叉查找树 它具有以下5个性质: 1、节点颜色必须是红色或者黑色 2、根节点是黑色 3、每个叶子节点(NIL节点、空节点)是黑色的 4、每个红色节点的两个子节点都是黑色 5、从任一节点到每个叶子的所有路径都包含数目相同的黑色节点 假设我们插入这些数据:12 23 34 40 45 67 78 89 90 100 110 120 130 140 1、插入12,12为根节点,根节点一定为黑;插入23,符合红黑树的基本性质,无需做出调整 2、插入45 不满足红色节点一定有两个黑色子节点,对12 节点左旋,23变成根,颜色变为黑色,12原来为黑色,旋转后这条路径多了一个黑色节点,所以为了满足性质5,必须将其颜色换为红色 3、插入34,不满足红色节点一定有两个黑色子节点,所以将34的父节点和叔叔节点 涂成 黑色,祖父节点变成红色,但23是根,必须为黑色,所以如上图所示 23,12,45节点颜色为黑色 4、插入40 插入数据情况基本就是这样,总结一下: 1、如果插入的节点,父节点为 ,叔叔节点(插入节点的父节点的兄弟节点)为 ,那么 就要把父节点和叔叔节点涂成 ,祖父节点涂成 (但如果是根节点涂成黑色)。 2、如果插入的节点,父节点为 ,父节点是祖父节点的右支,叔叔节点为 ,且 (1)要插入的节点为父节点的右支,那么对其 祖父节点左旋。就相当于: (2

红黑树

左心房为你撑大大i 提交于 2020-01-23 19:20:02
红黑树的存在是为了改变二叉排列树的性能,在最坏的时候,生成的二叉排列树就是链表,这种情况完全没有了二叉排列数的折半查找的优势,时间复杂度变回O(n) 什么是红黑树 红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则。这些规则使红黑树保证了一种平衡,插入、删除、查找的最坏时间复杂度都为 O(logn)。正是因为这个,它的统计性能好于平衡二叉树;在 Java 集合框架中,很多部分(HashMap, TreeMap, TreeSet 等)都有红黑树的应用 红黑树的特性 在原来二叉查找树的基础上,红黑树又增加了以下几个要求 每个节点要么是红色,要么是黑色 根节点永远是黑色 每个叶子节点都是黑色(这里的叶子节点指的是为空的节点) 红色节点的两个子节点一定是黑色 从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点 同时他也要满足二叉排序树的基本性质:树中的任何节点的值大于它的左子节点,且小于它的右子节点。 这些性质保证了没有一条路径会比其他路径长处两倍,因而,红黑树是相对是接近平衡的二叉树 红黑树的基本操作 1. 插入 对于新插入的节点要先当作按照查找树的规则进行插入,同时也要将他涂成红色,涂成红色是因为: ① 在性质5中,从任意的节点出发到空叶子节点,经过的黑色节点个数是相同的,那么如果你当作黑色系节点插入,肯定会违背这个性质 ②

动画 | 什么是红黑树?(与2-3-4树等价)

走远了吗. 提交于 2020-01-23 13:40:58
二分搜索树是为了快速查找而生,它是一颗二叉树,每一个节点只有一个元素(值或键值对),左子树所有节点的值均小于父节点的值,右子树所有的值均大于父节点的值,左右子树也是一颗二分搜索树,而且没有键值相等的节点。它的查找、插入和删除的时间复杂度都与树高成比例,期望值是O(log n)。 但是插入数组如[],二分搜索树的缺点就暴露出来了,二分搜索树退化成线性表,查找的时间复杂度达到最坏时间复杂度O(n)。 动画:二分搜索树退化成线性表 那有没有插入和删除操作都能保持树的完美平衡性(任何一个节点到其叶子节点的路径长度都是相等的)? 有,B树。B树是一种自平衡的树,根节点到其叶子节点的路径高度都是一样的,能够保持数据有序(通过中序遍历能得到有序数据)。B树一个节点可以拥有2个以上的子树,如2-3树、2-3-4树甚至2-3-4-5-6-7-8树,它们满足二分搜索树的性质,但它们不属于二叉树,也不属于二分搜索树。 2-3-4树的完美平衡,每条从根节点到叶子节点的路径的高度都是一样的 2-3-4树有以下节点组成: 2-节点,含有一个元素(值或键值对)和两个子树(左右子树),左子树所有的值均小于父节点的值,右子树所有的值均大于父节点的值; 3-节点,含有两个元素和三个子树,左子树所有的值均小于父节点最小元素的值,中间子树所有的值均位于父节点两个元素之间,右子树所有的值均大于父节点最大元素的值; 4-节点