红黑树 - 插入篇

红黑树定义

  • 根节点是黑色的

  • 节点要么为红色,要么为黑色

  • 任意节点到其子孙节点,所经过路径上的包含相同数量的黑色节点

  • 红色节点,其子节点不能为红色

  • 所有叶子节点皆为黑色,此叶子节点指的是为空(NIL或NULL)的叶子节点,通常省略不画。

    红黑树变换 (6).png

红黑树染色,旋转规则

第一个节点(作为初始根)颜色为黑色,所有新插入节点颜色都为红色

  • 1 若插入节点父节点为黑色,则直接插入

  • 2 若插入节点父节点为红色

    • 2.1 若插入节点叔叔节点为红色,则进行染色,父节点与叔节点转为黑色,祖父节点转为红色,矛盾向上转移。

    红黑树变换 (5).png

    • 2.2 若插入节点叔叔节点为黑色
      • 2.2.1 若插入节点父节点的偏向,与父节点与其祖父节点的偏向一致。换句话说,插入节点是其父节点的右(左)子树,且父节点是其插入节点的祖父节点的右(左)子树,则偏向一致。此时,第一步,将父节点转为黑色祖父节点转为红色。第二步,以祖父节点为基准,进行左旋。

        红黑树变换.png

      • 2.2.2 若插入节点父节点的偏向,与父节点与其祖父节点的偏向不一致。此时,第一步,先进行节点旋转,以父节点为基准进行右旋,此时致使三个节点偏向一致,然后进行上一种偏向一致操作。

        红黑树变换 (2).png

  • 补充

    1. 旋转的本质,其实就是使节点的偏向一致,无非去考虑什么时候左旋,什么时候右旋
    2. 染色与旋转的规则,都是为定义所服务的
    3. 一个问题,染色会导致矛盾上移。当上移到根节点的时候,该怎么处理呢

红黑树插入具体示例

以插入int[] a = {10, 18, 16, 12, 13, 17, 15, 14, 9, 8,7}数组为案例。

  1. 插入节点10,初始节点,设为根节点,颜色为色。

未命名文件.png

  1. 插入节点18,颜色为色,因父节点为色,直接插入。

红黑树流程2.png

  1. 插入节点16,颜色为色,因父节点为色,且叔叔节点为色(根据定义所有叶子节点皆为黑色),所以符合2.2.2条件,先旋转,在染色,在旋转

红黑树流程3.png

  1. 插入节点12,颜色为色,因父节点为色,且叔叔节点也为色,符合2.1条件,父节点与叔节点变色,祖父节点变色,又因为祖父节点为根节点,所以再次变为色(定义:根节点为黑色)。

红黑树流程4.png

  1. 插入节点13,颜色为色,因父节点为色,且叔叔节点为色,与插入节点16情况不同的是,其偏向一致,与2.2.1条件所描述的相同,所以直接染色,在旋转。

红黑树流程5.png

  1. 插入节点17,颜色为色,因父节点为色,直接插入。

红黑树流程6.png

  1. 插入节点15,颜色为色,因父节点为色,且叔叔节点也为色,符合2.1条件,父节点与叔节点变色,祖父节点变色,此时,已满足红黑树平衡条件,无需旋转。

红黑树流程7.png

  1. 插入节点14,颜色为色,因父节点为色,且叔叔节点为色,且父子节点偏向不一致。符合2.2.2条件,先旋转,在染色,在旋转。

红黑树流程8.png

  1. 插入节点9,颜色为色,因父节点为色,直接插入。

红黑树流程9.png

  1. 插入节点8,颜色为色,因父节点为色,且叔叔节点为色,且父子节点偏向一致。符合2.2.1条件,先染色,在旋转

红黑树流程10.png

  1. 插入节点7,颜色为色,因父节点为色,且叔叔节点也为色,符合2.1条件,父节点与叔节点变色,祖父节点变色。又因为节点9与节点12处于连续状态,不满足定义,根据2.2.1条件,节点12节点16,根据定义任意节点到其子孙节点,所经过路径上的包含相同数量的黑色节点,所以此时将根节点变为黑色,以不满足定义,故根据2.2.1,进行旋转。

红黑树流程11.png

补充

猜你喜欢

转载自juejin.im/post/7035463218604556325