数据结构之「AVL树」

作者: 清尘闲聊 | 来源:发表于2019-03-31 08:56 被阅读16次

前言

二叉搜索树在一般情况下它的查找时间复杂度是 O(log n)。但在一些特殊的情况下,它会退化为斜树变成线性结构,导致查询效率大大降低,根本发挥不出折半查找的优势。因此,就需要一种平衡的二叉搜索树来达到我们期望查询时间复杂度为 O(log n) 的数据结构,那就是平衡二叉搜索树

平衡二叉搜索树

平衡二叉搜索树又叫 AVL树,它具有以下性质:
1.任一节点对应的两棵子树的最大高度差为 1。
2.两棵子树都是平衡二叉树。

通过保证上面 2 条规则,因此它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是O(log n)。因此,它是一颗相对稳定的树。

为了保证左右 2 棵子树的最大高度差为 1,我们需要在插入和删除时,对树进行旋转操作,以保证树的平衡性。有 2 种基本的操作,那就是左旋右旋

树的左旋和右旋
在进行左右旋转时,会出现四种可能性:
1.左左形态
当 x 是 y 的左节点,y 又是 z 的左节点时,这个时候只需要把 y 节点向右旋转即可。如下图:
左左
2.左右形态
当 x 是 y 的右节点,而 y 又是 z 的左节点时,需要先把 y 左旋,变成 左左形态,然后再把 z 右旋。如下图:
左右
3.右右形态
当 x 是 y 的右节点, y 又是 z 的右节点时,这时候只需要把 y 节点向左旋转即可。如下图:
右右
4.右左形态
当 x 是 y 的左节点,而 y 又是 z 的右节点时,需要先把 y 右旋,变成 右右形态,然后再把 z 左旋。如下图:
右左

平衡二叉树的实现

public class AVLTree {

    //获取左右节点的高度差
    public int getBalance(Node n) {
        if (n != null) {
            return (getHeight(n.left) - getHeight(n.right));
        }
        return 0;
    }
    //获取节点的高度
    public int getHeight(Node n) {
        if (n != null) {
            return n.height;
        }
        return 0;
    }

    //右旋
    public Node rightRotate(Node y) {
        Node x = y.left;
        Node T2 = x.right;

        // 旋转
        x.right = y;
        y.left = T2;

        // 更新节点的高度
        x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
        y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;

        return x;
    }

    //左旋
    public Node leftRotate(Node x) {
        Node y = x.right;
        Node T2 = y.left;

        // 旋转
        y.left = x;
        x.right = T2;

        // 更新节点的高度
        x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
        y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;

        return y;
    }

    public Node insert(Node node, int data) {
        if (node == null) {
            return (new Node(data));
        }
        if (node.data > data) {
            node.left = insert(node.left, data);
        } else {
            node.right = insert(node.right, data);
        }
        // 更新节点的高度
        node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;

        int balDiff = getBalance(node);

        // 右旋
        if (balDiff > 1 && data < node.left.data) {
            return rightRotate(node);
        }

        // 左旋
        if (balDiff < -1 && data > node.right.data) {
            return leftRotate(node);
        }

        // 先左旋在右旋
        if (balDiff > 1 && data > node.left.data) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }

        // 先右旋在左旋
        if (balDiff < -1 && data < node.right.data) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }

        return node;
    }
}
class Node {
    int data;
    Node left;
    Node right;
    int height;

    public Node(int data) {
        this.data = data;
        height = 1;
    }
}

总结

二叉搜索树的不稳定性,就有可能退化为近似链或链,查询时间复杂度就退化为 O(n)。当 n 很大的时候,性能就大大降低,达不到折半的效果。因此,我们需要一个平衡的二叉搜索树。

平衡二叉树是通过对树节点的左旋和右旋来保证树的平衡性,也就是保证左右子树的高度差不超过 1。

在对树进行左旋和右旋时,有四种形态分别是:左左左右右右右左

因此,平衡二叉树的查找、插入和删除在平均和最坏情况下的时间复杂度都是O(log n)。

PS:
清山绿水始于尘,博学多识贵于勤。
我有酒,你有故事吗?
公众号:「清尘闲聊」。
欢迎一起谈天说地,聊代码。

相关文章

  • 数据结构07-AVL树

    数据结构07-AVL树 一、AVL树的基本概念 1.AVL树 AVL树是一种每一个节点的左子树与右子树的高度差最多...

  • 重点汇总-python-gitbook-重要点学习-4-数据结构

    数据结构 - 红黑树 红黑树与AVL的比较: AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转...

  • 数据结构之「AVL树」

    前言 二叉搜索树在一般情况下它的查找时间复杂度是 O(log n)。但在一些特殊的情况下,它会退化为斜树变成线性结...

  • 数据结构之AVL树

    平衡树和AVL 我们先来回忆一下二分搜索树[https://www.jianshu.com/p/cd8abc35f...

  • 数据结构之AVL树

    AVL树定义 AVL树任意节点的两棵子树的高度差绝对值最大为1(和红黑树相比简洁了很多) 与红黑树对比 相同点 都...

  • Android重学系列 红黑树

    背景 红黑树,是一个比较复杂的数据结构。让我们分析一下,整个AVL树的性质。AVL最明显的特点就是,每个节点左右子...

  • 死磕Redis5.0之跳跃表

    为什么选择跳跃表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等。想象...

  • Redis:跳表SkipList

    原文链接:SkipList 跳表 为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay...

  • 数据结构—树—AVL

    AVL概述 AVL的删除

  • 数据结构-AVL树

    平衡(Balance) 当节点数量固定时,左右子树的高度越接近,这棵二叉树就越平衡(高度越低) 平衡二叉搜索树(B...

网友评论

    本文标题:数据结构之「AVL树」

    本文链接:https://www.haomeiwen.com/subject/rydsbqtx.html