AVL树的原理及代码实现

AVL树是一种自平衡二叉查找树,由Adelson-Velsky和Landis提出,确保任何节点的两个子树高度差不超过1。本文介绍了AVL树的基本概念、平衡度、插入与删除操作中的旋转调整,以及如何通过旋转操作维护树的平衡,确保操作时间复杂度为O(logn)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

如果你还没有学习过二叉查找树,那么请你先去看看二叉查找树,因为AVL树便是从二叉查找树进化而来的,不看的话你无法理解AVL树。

链接:二叉查找树的原理及实现

如果你已经学习了二叉查找树,你会觉得二叉查找树性能在各方面都很好,就只有一丢丢的小毛病,那就是当数据非常坑时,二叉查找树退化成了一条单链表,这样各种操作的时间复杂度都变为O(n)了,怎么办呢,今天所要学习的AVL树便以其惊艳四座的高端技巧解决了这一问题,使其在任何情况下的各种操作复杂度都为O(logn)。

AVL树

AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的。
它是最先发明的自平衡二叉查找树,也被称为高度平衡树。

在介绍AVL树时,首先要介绍一个概念——平衡度。

平衡度 = 左子树的高度 - 右子树的高度

当树上所有节点平衡度为-1,0,1时,我们认为这棵树是平衡的,当有节点的平衡度绝对值 > 1时,我们认为这棵树是不平衡的,我们就要对这个节点进行调整。

基本实现

存储实现:

AVL树与二叉查找树一样使用二叉链表实现,这样能够很好的理解,每个节点有一个元素存储值,两个指针分别指向它的左子树和右子树,还有一个元素来存储该节点的高度。

template <class elemType>
class AvlTree{
private:
    
    struct node{
        elemType data;
        node *left;
        node *right;
        int height;
        
        node(const elemType &x, node *ln, node *rn, int h = 1):data(x), left(ln), right(rn), height(h){}
    };
    
    node *root;
}

find操作:

AVL树的操作与二叉查找树的find操作原理一模一样,这里就不详细讲了,想看的可以去文首的二叉查找树的链接里看。

此处代码使用了非递归实现:

    elemType *find(const elemType &x){
        node *t = root;
        while(t != NULL && t -> data != x){
            if(t -> data > x){
                t = t -> right;
            }
            else{
                t = t -> left;
            }
        }
        
        if(t == NULL){
            return NULL;
        }
        else{
            return &(t -> data);
        }
    }

midOrder操作:

也与二叉查找树完全相同,中序遍历输出整个树的值,结果必然是一个从小到大序列。

    void midOrder(){
        midOrder(root);
    }
    void midOrder(node *p){
        if(p == NULL){
            return;
        }
        midOrder(p -> left);
        cout << p -> data << ' ';
        midOrder(p -> right);
    }

insert操作:

insert操作就与二叉查找树有些不同了,它不但要找到合适位置插入元素,还要判断插入后是不是破坏了树的平衡性,如果破坏了要对树进行调整。

先列举几种失去平衡的情况:

LL: 在节点的左子树的左子树上插入节点,使节点平衡度变为2,失去平衡

LR:在节点的左子树的右子树上插入节点,使节点平衡度变为2,失去平衡

RR:在节点的右子树的右子树上插入节点,使节点平衡度变为-2,失去平衡

RL:在节点的右子树的左子树上插入节点,使节点平衡度变为-2,失去平衡

下面来说解决办法:

LL单旋转:

如图,k2失去平衡,k2的左子树根节点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值