数据结构 平衡二叉排序树(AVL树)

本文详细介绍了AVL树的定义、性质和平衡修复策略,包括LL旋转、RR旋转、LR旋转和RL旋转。同时,提供了AVL树的插入和删除操作,每次操作后会检查并修复平衡状态,确保查找效率保持在O(logn)。此外,还展示了相关宏定义和结构体定义,用于计算节点高度、平衡因子和调整高度。
摘要由CSDN通过智能技术生成

平衡二叉排序树(AVL树)

定义

  • 平衡二叉树
    • 任意一个节点其左右子树高度不超过1
    • 二叉排序树插入、删除、查找平均时间复杂度O(logn)
二叉排序树插入删除查找
平均时间复杂度O(logn)O(logn)O(logn)
最差时间复杂度O(n)O(n)O(n)
  • 当二叉排序树的节点只有左子树或者只有右子树,二叉排序树退化为单链表
  • 为了避免二叉排序树退化为单链表,所以要求二叉树平衡的(太苛刻了)所以在实际应用中都是用红黑树来取代(大致平衡) 查找的效率都能维持在O(logn)
  • AVL 插入和二叉排序树的插入是一样的,如果插入之后失去平衡,就需要修复
  • AVL 删除和二叉排序树的删除是一样的,如果删除之后失去平衡,就需要修复

平衡二叉树排序树修复

  • LL 左子树高于右子树 并且 左子树的左儿子高于右儿子
    • 右旋
  • LR 左子树高于右子树 并且 左子树的左儿子低于右儿子
    • 左旋左子树 然后右旋
  • RR 左子树低于右子树 并且 右子树的左儿子低于右儿子
    • 左旋
  • RL 左子树低于右子树 并且 右子树的左儿子高于右儿子
    • 右旋右子树 然后左旋

二叉平衡树实现

结构体定义

#define SUCCESS 0
#define FAILURE -1

typedef int ElemType;

// 平衡二叉排序树节点
struct AVLNode {
    ElemType elem;  // 元素
    struct AVLNode *lchild, *rchild; // 左右子树
    size_t height;  // 节点的高度   记录平衡因子
};
// 平衡因子 = 左子树高度 - 右子树高度
// 平衡二叉树 每一个节点  平衡因子  -1 0 1

主要功能声明

// 插入元素
int insert_avltree(AVLTree *ptree, ElemType elem);

// 删除元素
int remove_avltree(AVLTree *ptree, ElemType elem);

AVL树基本操作

// 右旋 LL
struct AVLNode* LL_rotation(struct AVLNode *node);

// 左旋 RR
struct AVLNode* RR_rotation(struct AVLNode *node);

// LR
struct AVLNode* LR_rotation(struct AVLNode *node);

// LR
struct AVLNode* RL_rotation(struct AVLNode *node);

// 对*ptree节点进行修复
static void avltree_repaire(AVLTree *ptree)

宏函数

// 求一个节点的高度
#define HEIGHT(node) (((node) == NULL) ? 0 : (node)->height)

// 求一个节点的平衡因子     node != NULL
#define BAANCE(node) ((HEIGHT((node)->lchild)) - (HEIGHT((node)->rchild)))

// 调整一个节点的高度
#define REHEIGHT(node) (HEIGHT((node)->lchild) > HEIGHT((node)->rchild) ? \
                    (HEIGHT((node)->lchild) + 1) : (HEIGHT((node)->rchild) + 1))

功能和操作实现

右旋 LL_rotation
/*
       |                                      |
      node                                   left 
      /  \          --node进行右旋-->        /   \
    left right     <--left进行左旋--       ll    node
    /  \                                          /  \
   ll  lr                                        lr  right

*/
// 右旋
struct AVLNode* LL_rotation(struct AVLNode *node)
{
    struct AVLNode *left = node->lchild;
    node->lchild = left->rchild;
    left->rchild = node;
    node->height = REHEIGHT(node); // 调整节点node的高度
    return left;
}
左旋 RR_rotation
/*
        |                                          |
       node                                       right
       /   \          --对node进行左旋-->        /   \
    left   right      <--对right进行右旋--     node  rr
           /  \                                /  \
          rl   rr                            left  rl
*/
// 左旋
struct AVLNode* RR_rotation(struct AVLNode *node)
{
    struct AVLNode *right = node->rchild;
    node->rchild = right->lchild;
    right->lchild = node;
    node->height = REHEIGHT(node);
    return right;
}
LR LR_rotation
/*
       |                           |                            |
      node                        node                         lr 
     /   \        对left左旋      /  \        对node进行右旋     /   \
   left right                    lr  right                  left  node
    /  \                       /  \                         /  \   /  \
   ll  lr                     left lrr                     ll lrl lrr right
       / \                    / \ 
    lrl  lrr                 ll lrl
    
    lrl  lrr 允许为NULL 
*/
struct AVLNode* LR_rotation(struct AVLNode *node)
{
    node->lchild = RR_rotation(node->lchild); // 左旋
    return LL_rotation(node); // 右旋
}
RL RL_rotation
/*
       |                      |                          |
      node                   node                       rl 
     /   \      right右旋   /   \        node左旋      /    \
  left   right             left  rl                  node  right
         /  \                   / \                  /  \   /  \
        rl   rr               rll right            left rll rlr  rr
       / \                         / \
      rll rlr                     rlr rr
      
      rll  rlr允许为空 
*/
struct AVLNode* RL_rotation(struct AVLNode *node)
{
    node->rchild = LL_rotation(node->rchild); // 右旋
    return RR_rotation(node); // 左旋
}
对*ptree节点进行修复 avltree_repaire
static void avltree_repaire(AVLTree *ptree)
{
    int lh = HEIGHT((*ptree)->lchild); // 左子树高度
    int rh = HEIGHT((*ptree)->rchild); // 右子树高度
    if (lh - rh == 2) {
        struct AVLNode *left = (*ptree)->lchild;
        if (HEIGHT(left->lchild) > HEIGHT(left->rchild)) { // LL
            *ptree = LL_rotation(*ptree);
        } else { // LR
            *ptree = LR_rotation(*ptree);
        }
    } else if (rh - lh == 2) {
        struct AVLNode *right = (*ptree)->rchild;
        if (HEIGHT(right->rchild) > HEIGHT(right->lchild)) { // RR
            *ptree = RR_rotation(*ptree);
        } else { // RL
            *ptree = RL_rotation(*ptree);
        }
    }
    // 不管需不需要旋转  节点的高度始终都要调整
    (*ptree)->height = REHEIGHT(*ptree);
}
插入元素 insert_avltree
int insert_avltree(AVLTree *ptree, ElemType elem)
{
    assert(ptree != NULL);
    if (*ptree == NULL) {  // NULL 为要插入的节点 (ptree为二级指针)
        struct AVLNode *node = (struct AVLNode*)malloc(sizeof(struct AVLNode));
        if (node == NULL) {
            return FAILURE;
        }
        node->elem = elem;
        node->lchild = node->rchild = NULL;
        node->height = 1;
        *ptree = node;
        return SUCCESS;
    }
    int ret = FAILURE;
    if (elem < (*ptree)->elem) {
        ret = insert_avltree(&(*ptree)->lchild, elem);
    } else if ((*ptree)->elem < elem) {
        ret = insert_avltree(&(*ptree)->rchild, elem);
    }
    if (ret == SUCCESS) {
        avltree_repaire(ptree); // *ptree进行修复
    }
    return ret;
}
删除元素 remove_avltree
int remove_avltree(AVLTree *ptree, ElemType elem)
{
    assert(ptree != NULL);
    if (*ptree == NULL) {
        return FAILURE;
    }
    int ret = FAILURE;
    if (elem < (*ptree)->elem) {
        ret = remove_avltree(&(*ptree)->lchild, elem);
    } else if ((*ptree)->elem < elem) {
        ret = remove_avltree(&(*ptree)->rchild, elem);
    } else {
        struct AVLNode *node = *ptree;
        if (node->lchild != NULL && node->rchild != NULL) {
            for (node = node->lchild; node->rchild != NULL; node = node->rchild); // 找到左子树最大值
            (*ptree)->elem = node->elem;
            ret = remove_avltree(&(*ptree)->lchild, node->elem); // 删除最大值的原节点
        } else {
            *ptree = node->lchild != NULL ? node->lchild : node->rchild;
            free(node);
            return SUCCESS;
        }
    }
    if (ret == SUCCESS) {
        avltree_repaire(ptree);  // 删除后要修复
    }
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值