红黑树——2.插入

      红黑树是一种自平衡二叉查找树。它的统计性能据说要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除等操作。
      牢记着5条性质:
        性质1. 节点是红色或黑色
        性质2. 根是黑色
        性质3. 所有叶子都是黑色(叶子是NIL节点)
        性质4. 如果一个节点是红的,则它的两个儿子都是黑的
        性质5. 从任一节点到其叶子的所有简单路径都包含相同数目的黑色节点。

对红黑树的插入操作和删除操作会导致不再符合红黑树的性质,可以通过重图颜色和旋转节点来保持红黑树的特性。
所以,请记住对红黑树的所有操作,目标都是为了保持其特定的性质。以下一些做法,你可以先记住他,以后慢慢理解。

插入操作
插入操作可以概括为以下几个步骤:
    (1) 查找要插入的位置,时间复杂度为:O(N)
    (2) 将新节点的color赋为红色
    (3) 自下而上重新调整该树为红黑树
【 注)第(1)步的查找方法跟普通二叉查找树一样,第(2)步之所以将新插入的节点的颜色赋为红色,是因为:如果设为黑色,就会导致根到叶子的路径上有一条路上,多一个额外的黑节点,这个是很难调整的。但是设为红色节点后,可能会导致出现两个连续红色节点的冲突,那么可以通过颜色调换(color flips)和树旋转来调整,这样简单多了。】

    重点在(3),下面详细介绍(3)的细节:
    前提假设:设要插入的节点为N,其父节点为P,其父亲G的兄弟节点为U(即P和U是同一个节点的两个子节点)。
需要进一步学习的,请访问:
http://blog.chinaunix.net/uid-24774106-id-355157.html  红黑树插入背后的哲学
http://julyblog.blog.163.com/blog/static/18355431320113151014144/  红黑树从头至尾插入和删除结点的全程演示图
http://dongxicheng.org/structure/red-black-tree/  数据结构之红黑树

    插入节点时,会出现以下情形:
    情形1: 新节点N位于树的根上,没有父节点
    情形2: 新节点的父节点P是黑色
    情形3: 父节点P、叔叔节点U,都为红色,
    情形4: 父节点P是红色,叔叔节点U是黑色或NIL;
             插入节点N是其父节点P的右孩子,而父节点P又是其父节点的左孩子。
    情形5: 父节点P是红色,而叔父节点U 是黑色或NIL,
             要插入的节点N 是其父节点的左孩子,而父节点P又是其父G的左孩子。
   
    插入节点时,我们总是考虑插入节点N为红色;
    对于情形1,比较简单,将N节点重图为红色即可
    对于情形2,就更简单了,直接插入即可
    通常我们需要讨论的是情形3、4、5,以下详细介绍:
    对于情形3,如下图所示,我们将P和U重绘为黑色并重绘节点G为红色(用来保持性质5)。现在新节点N有了一个黑色的父节点P,因为通过父节点P或叔父节点U的任何路径都必定通过祖父节点G,在这些路径上的黑节点数目没有改变。 但是,红色的祖父节点G的父节点也有可能是红色的,这就违反了性质4。为了解决这个问题,我们在祖父节点G上递归调整颜色。(重点记住,这是情形3,由于变换会产生情形3、4或者5,就可以递归用这3种情形,直至满足所有性质为止)
   
    对于情形4,如下图所示,我们对P进行一次左旋转调换新节点和其父节点的角色; 接着,按情形3来处理以前的父节点P以解决仍然失效的性质4。
   
    对于情形5,如下图所示,对祖父节点G 的一次右旋转; 在旋转产生的树中,以前的父节点P现在是新节点N和以前的祖父节点G 的父节点, 然后交换以前的父节点P和祖父节点G的颜色,结果的树满足性质4,同时性质5[4]也仍然保持满足。
   

    以上即是红黑树的插入操作,大家可以按照以上要求自行绘制一张图试试!
    分享一条经验,请把二叉树当成是一个链条,根结点处有一根钉子,当你拖拽链条的一端是,链条会如何?拽链条的目的就是为了保持链条两端平衡(即两边度之差的绝对值不>1)。再以此类推!
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值