Java 平衡二叉树的旋转


平衡二叉树的旋转

  • 在构建一棵平衡二叉树的过程中,当有新的节点要插入时,检查是否因插入后而破坏了树的平衡,如果是,则需要做旋转去改变树的结构;
  • 由于在构建平衡二叉树的时候,当有新节点插入时,都会判断插入后时候平衡,这说明了插入新节点前,都是平衡的,即高度差绝对值不会超过1。当新节点插入后,有可能会有导致树不平衡,这时候就需要进行调整,而可能出现的情况就有4种,分别称作 左左,左右,右左,右右

1. 左旋(逆时针)

  • 将节点的右支往左拉,右子节点变成父节点,并把晋升之后多余的左子节点出让给降级节点的右子节点;
    Java 平衡二叉树的旋转
  • 如下图,将"15"节点进行左旋,让"15"自身把节点出让给"17"作为"17"的左树,使得"17"节点左右子树平衡,而"15"节点没有子树,左右也平衡了;
    Java 平衡二叉树的旋转

2. 右旋(顺时针)

  • 将节点的左支往右拉,左子节点变成了父节点,并把晋升之后多余的右子节点出让给降级节点的左子节点;
    Java 平衡二叉树的旋转

3. 左左

  • 左左即为在原来平衡的二叉树上,在节点的 左子树的左子树下,有新节点插入,导致节点的左右子树的高度差为2;
  • 如下图,为"10"节点的左子树"7",的左子树"4",插入了节点"5"或"3"导致失衡:Java 平衡二叉树的旋转
  • 左左调整其实比较简单,只需要 对父父父节点进行右旋 即可;
  • 如下图,对节点"10"进行右旋:
    Java 平衡二叉树的旋转

4. 左右

  • 左右即为在原来平衡的二叉树上,在节点的 左子树的右子树下,有新节点插入,导致节点的左右子树的高度差为2;

  • 如下图,为"11"节点的左子树"7",的右子树"9",插入了节点"10"或"8"导致失衡:Java 平衡二叉树的旋转

  • 左右这种情况,进行一次旋转是不能满足我们的条件的,正确的调整方式是,先将左右进行第一次旋转,左旋将父父节点左右调整成左左,然后再对父父父节点左左进行调整,从而使得二叉树平衡;

  • 如下图,先对上图的节点"7"进行左旋,使得二叉树变成了左左,之后再对"11"节点进行右旋,此时二叉树就调整完成(第二种左右也是如此):
    Java 平衡二叉树的旋转


5. 右左

  • 右左即为在原来平衡的二叉树上,在节点的右子树的左子树下,有新节点插入,导致节点的左右子树的高度差为2;

  • 如下图,为"11"节点的右子树"15",的左子树"13",插入了节点"12"或"14"导致失衡:
    Java 平衡二叉树的旋转

  • 如下图,前面也说了,右左跟左右其实互为镜像,所以调整过程就反过来,先对节点"15"进行右旋,使得二叉树变成右右,之后再对"11"节点进行左旋,此时二叉树就调整完成:
    Java 平衡二叉树的旋转


6. 右右

  • 右右即为在原来平衡的二叉树上,在节点的右子树的右子树下,有新节点插入,导致节点的左右子树的高度差为2;
  • 如下图,为"11"节点的右子树"13",的左子树"15",插入了节点"14"或"19"导致失衡:
    Java 平衡二叉树的旋转
  • 右右只需对节点进行一次左旋即可调整平衡,只需要对 父父父节点进行左旋 即可;
  • 如下图,对"11"节点进行左旋:
    Java 平衡二叉树的旋转