算法:红黑树

算法:红黑树

红黑树介绍

  红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。它是在1972年由鲁道夫·贝尔发明的,他称之为"对称二叉B树",它现代的名字是在Leo J. Guibas和Robert Sedgewick于1978年写的一篇论文中获得的。

  红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则。这些规则使红黑树保证了一种平衡,插入、删除、查找的最坏时间复杂度都为 O(logn)。它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用。比如在 Java 集合框架中,很多部分(HashMap, TreeMap, TreeSet 等)都有红黑树的应用,这些集合均提供了很好的性能。

  由于 TreeMap 就是由红黑树实现的,因此本文将使用 TreeMap 的相关操作的代码进行分析、论证

二叉查找树问题

  二叉排序树的性能取决于二叉树的层数:

  • 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访问性能近似于折半查找;
  • 最差时候会是 O(n),比如插入的元素是有序的,生成的二叉排序树就是一个链表,这种情况下,需要遍历全部元素才行.

  

  如上图所示,同一组元素构成的形态不同,性能不同的二种树形结构。所以呢,我们引入红黑树是要解决这种树形不平衡的问题

红黑树的性质

  红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色。在二叉查找树的性质之上,红黑树还有如下的一些性质:

  1.节点是或者黑色,但是根节点一定是黑色

  2.所有叶子节点都是黑色(叶子是NIL节点)

  3.每个红色节点必须有两个黑色子节点,红色节点不连续,但是黑色节点是可以连续的

  4.从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。

  

树的旋转知识

  当我们在对红黑树进行插入和删除等操作时,对树做了修改,那么可能会违背红黑树的性质

  为了继续保持红黑树的性质,我们可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后,继续保持它的性质或平衡

  树的旋转,分为左旋和右旋,以下借助图来做形象的解释和介绍:

  

左旋

  从右往左看是左旋,首先我们要左旋X,以X-Y为轴左转,X到达原先a的位置,那谁来接替X的位置呢,当然是Y,也就是X本来就小于Y,Y到达X的位置后,X必然要当Y的左节点。那此时Y节点的左边指向X的话,那么原先指向的b应该去哪里呢,b大于X,小于Y,固然只能挂靠在X的右边C节点本来就大于Y,故仍然在Y的右边。同理A节点本来就小于X,故仍然在X的左边

TreeMap的实现代码

    private void rotateLeft(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> r = p.right; //r = 图 Y
            p.right = r.left; //
            if (r.left != null)
                r.left.parent = p;
            r.parent = p.parent;
            if (p.parent == null)
                root = r;
            else if (p.parent.left == p)
                p.parent.left = r;
            else
                p.parent.right = r;
            r.left = p;
            p.parent = r;
        }
    }

右旋

  右旋的思路同左旋,此处不在赘述。

TreeMap的实现代码

    private void rotateRight(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> l = p.left;
            p.left = l.right;
            if (l.right != null) l.right.parent = p;
            l.parent = p.parent;
            if (p.parent == null)
                root = l;
            else if (p.parent.right == p)
                p.parent.right = l;
            else p.parent.left = l;
            l.right = p;
            p.parent = l;
        }
    }

  

原文地址:https://www.cnblogs.com/MrSaver/p/9876380.html

时间: 2024-08-27 13:59:22

算法:红黑树的相关文章

算法---红黑树实现介绍(一)

一.概述 红黑树是一种经典的存储结构,就其本身来说是一个二叉查找树,只是在这个基础上,树的节点增加了一个属性用于表示颜色(红或黑).通过限制从根节点到叶子的各个路径的节点着色的限制,来保证不会有哪个路径会比其它的路径长度超过2倍,从而红黑树是接近平衡的. 一直以来没有把红黑树完全理解,总觉得太难,望而生畏,最近下决心要弄清楚,也是花了很长时间,不过总算是明白了.记录下来以便更好的理解. 二.红黑树的特点 作为红黑树,需要有这5个限制,如下: 1)树中的每个节点,要么是红色,要么是黑色 2)树的根

算法--红黑树实现介绍(二)

一.概述 在前一篇中我们回顾了红黑树的特点及添加的处理,可以得知红黑树首先是一个二叉查找树,在此基础上通过增加节点颜色的约束来使得红黑树近似平衡.当我们添加或者删除节点时,我们需要对树进行调整以使其重新满足红黑树.这涉及到节点颜色的变化及部分节点的旋转.关于节点的旋转,以及添加时的处理我们已经介绍完了,所以本文重点介绍红黑树的删除. 二.红黑树的特点 在介绍删除时,我们还是再来回顾一下红黑树的五个特点,如下: 1)节点的颜色是红色或者黑色 2)树的根节点为黑色 3)树的叶子节点为黑色 4)如果一

数据结构与算法-红黑树

前言 红黑树是工程中最常用到的一种自平衡二叉排序树,其和AVL树类似,都是在进行插入.删除时通过一定的调整操作来维持相对稳定的树高,从而获得较好的查询性能. 性质 1. 节点是红色或黑色. 2. 根节点是黑色. 3 每个叶节点(null节点)是黑色的. 4 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) 5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点. 维护红黑树形状(树高)的,主要就是4.5两条性质,性质4决定了最长的路径莫过于红黑间隔

算法-红黑树

之前的一片博客中关于二叉查找树在最差的情况是O(n),不能完全的达到O(lgN),在一棵还有N个节点的树中,如果树的高度为lgN,那么我们可以在lgN次比较内结束查找,不过动态插入保证树的平衡性代码量和额外的空间都会是很大的代价.为了保证查找树的平衡性,我们可以允许树中的节点可以保存多个键,标准的二叉树的节点我们可以称之为2-节点(一个键和两条链接),3-节点(含有两个键和三条链接),这就是2-3树.一个2-结点左链接小于该结点,右链接大于该节点.3-节点左链接小于所有键,中链介于两个键之间,右

15 2 用于查找的高级数据结构和算法 红黑树

算法导论 第三部分——基本数据结构——红黑树

红黑树 红黑树是一种二叉查找树,但在每个结点上增加了一个存储位表示结点的颜色,可以是RED或者BLACK.通过对任何一条从根到叶子的路径上各个着色方式的限制, 红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的.当二叉查找树的高度较低时,这些操作执行的比较快,但是当树的高度较高时,这些操作的性能可能 不比用链表好.红黑树(red-black tree)是一种平衡的二叉查找树,它能保证在最坏情况下,基本的动态操作集合运行时间为O(lgn). 1.红黑树的性质 #define RED 0

红黑树之插入

1.红黑树 (1).概念 i>每个结点不是红的就是黑的: ii>根结点为黑的: iii>红结点的孩子必为黑结点: iv>(除了根结点)任一结点不管通过什么路径,到达叶子节点的黑结点数目一定相同: 总结概括:一头一脚黑,黑同红不连:根为黑,到脚(叶子节点)的黑结点相同,红结点不相连: 2.递归--->一般先写if结束语句 化非递归------>用while()循环和栈; enum{RED, BLACK}; 这个枚举是有值得,分别为0.1: 3.红黑树与AVL树  AVL树

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

二分搜索树是为了快速查找而生,它是一颗二叉树,每一个节点只有一个元素(值或键值对),左子树所有节点的值均小于父节点的值,右子树所有的值均大于父节点的值,左右子树也是一颗二分搜索树,而且没有键值相等的节点.它的查找.插入和删除的时间复杂度都与树高成比例,期望值是O(log n). 但是插入数组如[],二分搜索树的缺点就暴露出来了,二分搜索树退化成线性表,查找的时间复杂度达到最坏时间复杂度O(n). 动画:二分搜索树退化成线性表 那有没有插入和删除操作都能保持树的完美平衡性(任何一个节点到其叶子节点

红黑树&mdash;&mdash;算法导论(15)

1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极端情况是树变成了1条链)时,这些集合操作并不比在链表上执行的快.     于是我们需要构建出一种"平衡"的二叉搜索树.     红黑树(red-black tree)正是其中的一种.它可以保证在最坏的情况下,基本集合操作的时间复杂度是O(lgn). (2) 性质     与普通二叉搜索树不

编程算法 - 最小的k个数 红黑树 代码(C++)

最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出其中的最小k个数. 使用红黑树(multiset), 每次替换最大的值, 依次迭代. 时间复杂度: O(nlogk). 代码: /* * main.cpp * * Created on: 2014年6月29日 * Author: wang */ #include <iostream> #include <vector> #includ