红黑树
概念
R-B Tree,全称是Red-Black Tree,又称为“红黑树”,红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则。这些规则使红黑树保证了一种平衡,插入、删除、查找的最坏时间复杂度都为 O(logn)。
特性
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的两个子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
注意:
特性(3)中的叶子节点,是只为空(NIL或null)的节点。而且并叶子节点都是黑色。但 Java 实现的红黑树将使用 null 来代表空节点,因此遍历红黑树时将看不到黑色的叶子节点,反而看到每个叶子节点都是红色的。
性质 (4) 的意思是:从每个根到节点的路径上不会有两个连续的红色节点,但黑色节点是可以连续的。因此若给定黑色节点的个数 N,最短路径的情况是连续的 N 个黑色,树的高度为 N - 1;最长路径的情况为节点红黑相间,树的高度为 2(N - 1) 。
特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。但是红黑树并不是标准平衡二叉树,它以性质 5 作为一种平衡方法,使自己的性能得到了提升。
应用场景
它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率非常之高。
Java集合中的TreeSet和TreeMap和HashMap,C++ STL中的set、map,都是通过红黑树这种数据结构实现的。
linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块
CFS 背后的主要想法是维护为任务提供处理器时间方面的平衡(公平性)。这意味着应给进程分配相当数量的处理器
任务存储在以时间为顺序的红黑树中(由 sched_entity
对象表示),对处理器需求最多的任务 (最低虚拟执行时vruntime)存储在树的左側,处理器需求最少的任务(最高虚拟执行时)存储在树的右側。 为了公平。调度器然后选取红黑树最左端的节点调度为下一个以便保持公平性。
任务通过将其执行时间加入到虚拟执行时, 说明其占用 CPU 的时间,然后假设可执行。再插回到树中。这样,树左側的任务就被给予时间执行了,树的内容从右側迁移到左側以保持公平。
因此,每一个可执行的任务都会追赶其它任务以维持整个可执行任务集合的执行平衡。
CFS 不直接使用优先级而是将其用作同意任务运行的时间的衰减系数。低优先级任务具有更高的衰减系数。而高优先级任务具有较低的衰减系数。
这意味着与高优先级任务相比,低优先级任务同意任务运行的时间消耗得更快。 这是一个绝妙的解决方式,能够避免维护按优先级调度的运行队列。
优势:优先级保证下没有O(1)出色,但之所以没有用队列是为了保证其公平性
其他:nginx中,用红黑树管理timer等