热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

红黑树操作及实现

红黑树性质红黑树是广泛应用的平衡二叉搜索树之一(另外一种常见的平衡二叉搜索树是AVL树)。它是SGISTL唯一实现的一种搜索树;是关联容器的底部机制。
红黑树性质

        红黑树是广泛应用的平衡二叉搜索树之一(另外一种常见的平衡二叉搜索树是AVL树)。它是SGI STL唯一实现的一种搜索树;是关联容器的底部机制

       和AVL树所实现的平衡机制不同,但是同样适用了单旋转和双旋转操作修正树以保证平衡。

       红黑树的性质:

              1. 每个节点都被着上黑色或者红色。

              2. 根节点是黑色。

              3. 如果一个节点为红色,那么其子节点必须都为黑色。

              4. 任一节点到NULL指针的每条路径上必须包含相同数目的黑节点(将NULL视为黑色)。

        根据性质4,新插入的节点必须为红色,否则若新插入节点为黑色,则会使得该节点所在的路径上的黑节点个数增加。

        根据性质3,新插入节点的父节点必须为黑色(因为上面已经证明新插入节点必须为红色)。如果新节点插入后其父节点不为黑色则就要通过改变节点颜色和旋转树来保证红黑树性质。这就是下边插入操作比较麻烦所在。


红黑树的插入操作

约定: X为新节点,P为父节点,G为祖父节点,S为叔节点,GG为曾祖父节点。

分以下两种情况(父节点为黑或红)讨论插入操作:

一、 父节点为黑色

         直接插入X,插入操作完成。

二、父节点为

在第一部分已经讨论了,当父节点为红色,就会违背红黑树的性质,要调整树、改变节点颜色;此时,根据X插做左孩子还是右孩子和外围节点(S和GG)的颜色,再分以下几种情况讨论:

情况1: S为黑且X为左孩子

         在P和G之间做一次右旋转并改变G和P的颜色,即可。

        注意,旋转后可能会使树的高度相差大于1,例如当图中A、B为空但D或E不为空时。但这没关系,因为红黑树的平衡性本来就比AVL树弱,然而红黑树通常能导致良好的平衡状态。红黑树与AVL树平均效率相当,最坏情况下花费O(logN)。

情况2:S为黑且X为右孩子

        将P和X经过一次左旋转便可以变回情况1的情形;改变G和X的颜色,然后再对G做一次右旋转,即可。从这里的操作可以看出,所谓的双旋转其实就是两次单旋转

情况3:S为红

       分析此时所存在的问题:当S为红色的时候,如图5-15c所示,此时对P和G做一次旋转并改变X的颜色。此时,如果GG为黑色,那么该操作完成。但是,如果GG为红色,那么,旋转后的G和GG均为红色,不符合红黑树性质。

        解决方法:当遇到这种情况的时候,我们可以采取的方式有两种:上滤和自顶向下。以下分别介绍这两种方法。


上滤法

        当GG也为红色时,将情况3中提到的方法继续沿着根的方向上滤,直到不再有父子连续为红色的情况。

自顶向下法

         该方法是自上而下来保证S不会为红色的过程。在向下的过程中,当遇到一个节点X的两个儿子都是红色,就将X改为红色,而将两个儿子改为黑色。这种翻转只在X的父节点也为红色时才会破坏红黑树的性质,但是可以使用情况1或情况2中的方法做调整。这个过程能够保证不会遇到S节点为红色的情况;因为我们是自上而下调整的,在调整到G节点时,已经将可能存在的、P和S同时为红的情况破坏了。

        例如5-15e中,在寻找35插入的位置的过程中,我们从根节点开始寻找35应该插入的位置,其寻找的路径为图中虚箭头所示的方向,在该向下找过程中,当X为50的时候,X的两个孩子都是红色,此时将X改为红色,而将它的两个孩子改为黑色;然后继续找35应该插入的位置,这样就确保了不会存在S为红色的情况。


红黑树的删除操作



推荐阅读
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 深入理解Java中的Collection接口与Collections工具类
    本文详细解析了Java中Collection接口和Collections工具类的区别与联系,帮助开发者更好地理解和使用这两个核心组件。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 非公版RTX 3080显卡的革新与亮点
    本文深入探讨了图形显卡的进化历程,重点介绍了非公版RTX 3080显卡的技术特点和创新设计。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文探讨了在 ASP.NET MVC 5 中实现松耦合组件的方法。通过分离关注点,应用程序的各个组件可以更加独立且易于维护和测试。文中详细介绍了依赖项注入(DI)及其在实现松耦合中的作用。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
author-avatar
lksxq_468
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有