AVL树(自平衡二叉查找树)

本文深入探讨AVL树的概念,解析平衡因子的作用及其四种旋转调整机制:LL、RR、LR与RL型旋转,通过具体代码示例展示了如何在AVL树中插入新节点并保持树的平衡状态。

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

这篇文章我是先在博客园发布的:https://www.cnblogs.com/yinhao-ing/p/10732866.html

了解AVL树之前要先了解二叉查找树(BST),BST查找元素的时间复杂度平均是O(logN),最坏的情况是O(N),所有的元素都接在左子树(或者右子树)就相当于一串链表了。而AVL树会对子树过高的情况进行优化,这里有个平衡因子的概念,当前节点的平衡因子=左子树高度-右子树高度,AVL树的每一个节点的平衡因子的绝对值都是 < 2 的。

当一个新节点插入AVL树 ( 根节点为tree ) 的时候会有四种情况:

假设距离新节点最近的失衡节点为 t ( 的平衡因子的绝对值达到了2,且距离新节点最近)

1、LL型:新节点在 t1 的左孩子的左子树上,需要对 t 进行一次右旋操作;

2、RR型:新节点在 t 的右孩子的右子树上,需要对 t 进行一次左旋操作;

3、LR型:新节点在 t 的左孩子的右子树上,需要先对 t 的左孩子进行一次RR(左旋)操作,然后对 t 进行一次LL(右旋)操作;

4、RL型:新节点在 t 的右孩子的左子树上,需要先对 t 的右孩子进行一次LL(右旋)操作,然后对 t 进行一次RR(左旋)操作;

AVL树的实现代码如下:

#include "pch.h"
#include <iostream>
#include <queue>
#define ElementType int//自定义元素类型
using namespace std;
typedef struct node *AVLTree;
struct node {
    ElementType key;
    int Height = 0;
    AVLTree left = NULL, right = NULL;
};
int Height(AVLTree tree);//求树的高度
ElementType Max(ElementType a, ElementType b);
AVLTree insert(AVLTree tree, ElementType &key);//在AVLTree中插入节点
AVLTree LL_Rotation(AVLTree tree);//LL旋转
AVLTree RR_Rotation(AVLTree tree);//RR旋转
AVLTree LR_Rotation(AVLTree tree);//LR旋转
AVLTree RL_Rotation(AVLTree tree);//RL旋转

void levelTraversal(AVLTree tree);//层序遍历,用于测试

/*用main函数来测试,给N个不同的数据,插入AVL树中,然后层序输出*/
int main()
{
    int N;
    ElementType key;
    AVLTree tree = NULL;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        cin >> key;
        tree = insert(tree, key);
    }
    levelTraversal(tree);
}

AVLTree insert(AVLTree tree, ElementType &key) {
    if (tree == NULL) {
        tree = new node();
        tree->key = key;
    }
    else if (key < tree->key) {
        tree->left = insert(tree->left, key);//key小于当前节点的值时继续往其左子树递归地插入
        if (Height(tree->left) - Height(tree->right) >= 2) {//左子树与右子树的高度差达到2的时候就要对当前节点进行旋转,这里由于是递归地执行,保证了平衡因子达到2的节点是最接近插入点的
            if (key < tree->left->key)
                tree = LL_Rotation(tree);
            else
                tree = LR_Rotation(tree);
        }
    }
    else {
        tree->right = insert(tree->right, key);
        if (Height(tree->right) - Height(tree->left) >= 2) {
            if (key > tree->right->key)
                tree = RR_Rotation(tree);
            else
                tree = RL_Rotation(tree);
        }
    }
    tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;//当前节点的高度为其最大子树的高度+1
    return tree;
}

AVLTree LR_Rotation(AVLTree tree) {
    tree->left = RR_Rotation(tree->left);
    return LL_Rotation(tree);
}

AVLTree RL_Rotation(AVLTree tree) {
    tree->right = LL_Rotation(tree->right);
    return RR_Rotation(tree);
}

AVLTree RR_Rotation(AVLTree tree) {
    AVLTree tree2 = tree->right;
    tree->right = tree2->left;
    tree2->left = tree;
    tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;
    tree2->Height = Max(Height(tree2->right), tree->Height) + 1;
    return tree2;
}

AVLTree LL_Rotation(AVLTree tree) {
    AVLTree tree2 = tree->left;
    tree->left = tree2->right;
    tree2->right = tree;
    tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;
    tree2->Height = Max(Height(tree->left), tree->Height) + 1;
    return tree2;
}

int Height(AVLTree tree) {
    if (tree == NULL)
        return 0;
    return tree->Height;
}

ElementType Max(ElementType a, ElementType b) {
    return a > b ? a : b;
}

void levelTraversal(AVLTree tree)
{
    queue <AVLTree> Q;
    Q.push(tree);
    while (!Q.empty()) {
        AVLTree t = Q.front();
        Q.pop();
        cout << t->key << " ";
        if (t->left != NULL)
            Q.push(t->left);
        if (t->right != NULL) 
            Q.push(t->right);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值