Java 数据结构 - 红黑树:为什么工程中使用的平衡二叉查找树都是红黑树?

数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html)

1. 平衡二叉查找树

平衡二叉树:二叉树中任意一个节点的左右子树的高度相差不能大于 1。

从这个定义来看,完全二叉树、满二叉树其实都是平衡二叉树。常用的平衡二叉查找树的实现有两种:

  • AVL 树:最先被发明的平衡二叉查找树,它严格符合我刚讲到的平衡二叉查找树的定义,即任何节点的左右子树高度相差不超过 1,是一种高度平衡的二叉查找树。

  • 红黑树(Red-Black Tree):它从根节点到各个叶子节点的最长路径,有可能会比最短路径大一倍。红黑树是一种不严格的平衡二叉树。

平衡二叉查找树中 "平衡" 的意思,其实就是让整棵树左右看起来比较“对称”、比较“平衡”,不要出现左子树很高、右子树很矮的情况。这样就能让整棵树的高度相对来说低一些,相应的插入、删除、查找等操作的效率高一些。所以,只要树的高度不比 logn 大很多,查找的效率就不会降低很多,都是可以接收的。

2. 红黑树

红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

  • 性质1:节点是红色或黑色。
  • 性质2:根节点是黑色。
  • 性质3:每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存储数据;
  • 性质4:每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  • 性质5:从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树每次插入的节点颜色预设为红色,插入后,有可能会导致以上性质不满足,然后进行结点调整。红黑树之所以定义上述严格的特性,目的就是为了确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

  • (01) 特性(3)中的叶子节点,是只为空(NIL或null)的节点。

    (02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

2.1 时间复杂度

我们知道二叉查找树的时间复杂度是 O(height),和树的高度息息相关,如果是平衡二叉树则是 O(logn),如果退化为链表则为 O(n)。所以分析红黑树的时间复杂度,关键是分析红黑树的高度。

我们首先只考虑黑色结点,分析出所有黑色结点的高度。

  • 性质 3 规定,每个叶子节点都是黑色的空节点红黑树。也就是说,非叶子结点都有两个子结点。
  • 性质 5 中规定,从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。也就是说,所有的黑色高度都相同。
  • 如果只考虑黑色结点,所有的非叶子结点都有两个子结点,且高度相同。此时相当于一棵满二叉树的高度,黑色结点的高度为 logn。
  • 此时,我们将红色结点加上。性质 4 规定,不能有两个连续的红色结点。也就说即便最坏的情况,红色结点和黑色结点的高度一样。此时,红黑树的高度也不会大于 2logn。
  • 所以,由于红黑树的高度最大为 2logn,因此其时间复杂度为 O(logn)。

2.2 实现自己的红黑树

...


每天用心记录一点点。内容也许不重要,但习惯很重要!

Java数据结构和算法(二)顺序存储的树结构的更多相关文章

  1. Java数据结构和算法(二)--队列

    上一篇文章写了栈的相关知识,而本文会讲一下队列 队列是一种特殊的线性表,在尾部插入(入队Enqueue),从头部删除(出队Dequeue),和栈的特性相反,存取数据特点是:FIFO Java中queu ...

  2. Java数据结构和算法(三)顺序存储的树结构

    Java数据结构和算法(三)顺序存储的树结构 二叉树也可以用数组存储,可以和完全二叉树的节点一一对应. 一.树的遍历 // 二叉树保存在数组中 int[] data; public void preO ...

  3. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  4. Java数据结构和算法 - 二叉树

    前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...

  5. Java数据结构和算法(七)B+ 树

    Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...

  6. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  7. Java数据结构和算法(十四)——堆

    在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...

  8. Java数据结构和算法(九)——高级排序

    春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...

  9. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  10. Java数据结构和算法 - 栈和队列

    Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...

随机推荐

  1. python list unicode转中文显示

    [u'\u773c', u'\u8179\u90e8', u'\u4e94\u5b98', u'\u53e3\u8154', u'\u8179\u90e8', u'\u53e3\u8154'] str ...

  2. python urlretrieve 下载图片

    python 3中urlretrieve方法直接将远程数据下载到本地.为什么不行? 55 import re import urllib.request def getHtml(url): page ...

  3. leetcode258

    public class Solution { public int AddDigits(int num) { var str = num.ToString(); ; foreach (var c i ...

  4. IIS ashx

    win2008 IIS ashx http://127.0.0.1:801/testHandler.ashx 在服务器上用IE打开提示 HTTP 错误 404.17 - Not Found 请求的内容 ...

  5. 进程和创建线程的两种方法(threading.Thread)

    进程 如QQ 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理, 网络接口的调用等,进程就是各种资源管理的集合 线程:是操作系统最小的调度单位,是一串指令的结合 进程 要操作 ...

  6. Maven的几个常用plugin

    出自:https://www.cnblogs.com/zhangxh20/p/6298062.html maven-compiler-plugin 编译Java源码,一般只需设置编译的jdk版本 &l ...

  7. as2 针对加载进来的swf操作

    如果加载的子swf,里面的东西会随时发生变化,那么as2获取的子swf宽高也会不停在变动. 解决方法,就是在子swf里面控制设置方法,当as2需要准确获取子swf宽高时,迫使子宽高恢复到原本样子,这样 ...

  8. Redis 配置节

    Redis 后面的配置基于4.0.9版本=>>>不指定版本信息的配置说明都是耍流氓 比如在4.0.9中没有vm相关的及glueoutputbuf的配置信息 部分常用配置节(后面有详细 ...

  9. 18 subprocess模块(跟操作系统交互)

    1.基本概念介绍 我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的, 每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本 ...

  10. fiddler 修改request请求

    例:在request url后追加&test=1参数 在OnBeforeRequest函数中添加以下代码 if(oSession.uriContains("www.bing.com/ ...