扁扁笨算法-AVL树的插入与删除

发布时间 2023-08-21 13:29:32作者: 繁星依月

扁扁笨算法-AVL树的插入与删除

扁扁笨简述

扁扁笨算法是将不平衡子树打成一条中序遍历的直链(实质是一条升序链),然后按照寻找中点并提起中点构造二叉树的一种朴素做法。扁扁笨算法是一种确定平衡树调整结构之后填入数字的辅助手段,本身并没有什么出彩的地方。

理论简介

AVL树插入之后一般会产生左旋、右旋这样的操作。对于某些情况下,还需要进行先左旋再右旋,或者先右旋再左旋(双旋)的操作。本文提供了一种不需要考虑如何旋转直接调整不平衡AVL树的思路。

大致来说,先画出不平衡的二叉树,沿着插入结点往上寻找最小不平衡子树。

插入举例

第一个例子

如图所示AVL树,插入20结点,调整子树。

img

沿着20结点上溯,可以发现最小不平衡子树就是这棵树本身。

那么从这棵树的根结点出发,沿着上溯路径向下锁定三个结点。

img

然后采用扁扁笨策略,将这棵树打扁成链:{20,30,50,60,70,80},

而之前被选中的结点,将作为新树的最上层三个结点:{20,3050,60,70,80}.

具体来说,让50跑到根结点的位置,让30跑到根结点的左孩子位置,让70跑到根结点的右孩子位置。这个过程称为扁扁笨的上浮操作。

img

在这个例子中,没有浮起来的结点无法再充当下一层的根结点,直接连接即可得到调整之后AVL树。

img

第二个例子

如图所示AVL树,插入20结点,调整子树。

img

沿着67结点上溯,可以发现最小不平衡子树是以70结点为根结点的子树。

那么从这棵树的根结点出发,沿着上溯路径向下锁定三个结点。

img

然后采用扁扁笨策略,将这棵树打扁成链:{67,68,70},

而之前被选中的结点,将作为新树的最上层三个结点:{676870}.

对这三个结点执行扁扁笨的上浮操作,由于这棵树只有这三个结点,上浮后产生的子树就是调整后的子树。

img

将这棵子树接回原AVL树,即可得到最后调整过的AVL树。

img

第三个例子

如图所示AVL树,插入57结点,调整子树。

img

沿着57结点上溯,可以发现最小不平衡子树就是这棵树本身。

那么从这棵树的根结点出发,沿着上溯路径向下锁定三个结点。

img

然后采用扁扁笨策略,将这棵树打扁成链:

{21,26,50,55,57,60,63,66,67,68,70},

而之前被选中的结点,将作为新树的最上层三个结点:

{21,26,50,55,57,60,63,66,67,68,70}.

具体来说,让60跑到根结点的位置,让50跑到根结点的左孩子位置,让66跑到根结点的右孩子位置(扁扁笨的上浮操作)。

img

上浮操作后,我们对剩余的结点进行讨论:

如果区间段上只有两个结点,对于AVL树来说,谁作子树根结点都可以,但原则上与原本的AVL树保持一致。

如果区间段上有三个结点,取中间结点作为子树根结点。

区间段如果是更多的偶数结点或奇数结点,按照相同的逻辑类推即可。

img

整理一下,得到调整后的AVL树:

img

删除举例

如图所示AVL树,删除4结点,调整子树。

img

先找后驱结点进行替换,然后再进行调整。

img

沿结点5向下取,结点1或3任选其一

img

进行上浮操作

img

调整完成,接回原AVL树

img