【C语言】平衡二叉树——AVL树

平衡二叉树

  • 平衡二叉树是一种二叉排序树,其中每个结点的左子树和右子树的高度差最大等于1。
  • 距离插入结点最近的,且平衡因子(Banlance Factor)大于1的结点为根的子树,我们称为最小不平衡子树。

基本思想

在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,进行相应选转,使之成为新的平衡子树。

代码实现

/*
 * @Author: Xyh4ng
 * @Date: 2022-11-27 18:59:27
 * @LastEditors: Xyh4ng
 * @LastEditTime: 2022-11-27 20:56:50
 * @Description:
 * Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
 */
#include <stdio.h>
#include <stdlib.h>

typedef struct AVLNode
{
    int data;
    int bf;
    struct AVLNode *lchild, *rchild;
} AVLNode, *AVLTree;

void LeftRotation(AVLTree *T)
{
    AVLTree R;
    R = (*T)->rchild;
    (*T)->rchild = R->lchild;
    R->lchild = *T;
    *T = R;
}

void RightRotation(AVLTree *T)
{
    AVLTree L;
    L = (*T)->lchild;
    (*T)->lchild = L->rchild;
    L->rchild = *T;
    *T = L;
}

void LeftBanlance(AVLTree *T)
{
    AVLTree L, Lr;
    L = (*T)->lchild;
    switch (L->bf)
    {
    case 1: // LH
        RightRotation(T);
        (*T)->bf = L->bf = 0;
        break;
    case -1: // RH
        Lr = L->rchild;
        switch (Lr->bf)
        {
        case 1:
            (*T)->bf = -1;
            L->bf = 0;
            break;
        case 0:
            (*T)->bf = 0;
            L->bf = 0;
            break;
        case -1:
            (*T)->bf = 0;
            L->bf = 1;
            break;
        default:
            break;
        }
        Lr->bf = 0;
        LeftRotation(&(*T)->lchild);
        RightRotation(T);
    default:
        break;
    }
}

void RightBanlance(AVLTree *T)
{
    AVLTree R, Rl;
    R = (*T)->rchild;
    switch (R->bf)
    {
    case -1: // RH
        LeftRotation(T);
        (*T)->bf = R->bf = 0;
        break;
    case 1: // LH
        Rl = R->lchild;
        switch (Rl->bf)
        {
        case -1:
            (*T)->bf = -1;
            R->bf = 0;
            break;
        case 0:
            (*T)->bf = 0;
            R->bf = 0;
            break;
        case 1:
            (*T)->bf = 0;
            R->bf = 1;
            break;
        default:
            break;
        }
        Rl->bf = 0;
        RightRotation(&(*T)->lchild);
        LeftRotation(T);
    default:
        break;
    }
}

void InsertAVLTree(AVLTree *T, int key, int *taller)
{
    if (!*T)
    {
        *T = (AVLTree)malloc(sizeof(AVLNode));
        (*T)->data = key;
        (*T)->lchild = (*T)->rchild = NULL;
        (*T)->bf = 0;
        *taller = 1;
    }
    else
    {
        if (key == (*T)->data)
        {
            *taller = 0;
            return;
        }
        else if (key < (*T)->data)
        {
            InsertAVLTree(&(*T)->lchild, key, taller);
            if (*taller == 1)
            {
                switch ((*T)->bf)
                {
                case 1: // LH
                    LeftBanlance(T);
                    *taller = 0;
                    break;
                case 0: // EH
                    (*T)->bf = 1;
                    *taller = 1;
                    break;
                case -1: // RH
                    (*T)->bf = 0;
                    *taller = 0;
                    break;

                default:
                    break;
                }
            }
        }
        else
        {
            InsertAVLTree(&(*T)->rchild, key, taller);
            if (*taller == 1)
            {
                switch ((*T)->bf)
                {
                case 1: // LH
                    (*T)->bf = 0;
                    *taller = 0;
                    break;
                case 0: // EH
                    (*T)->bf = -1;
                    *taller = 1;
                    break;
                case -1: // RH
                    RightBanlance(T);
                    *taller = 0;
                    break;

                default:
                    break;
                }
            }
        }
    }
}

void MidTraversal(AVLTree T)
{
    if (!T)
    {
        return;
    }
    else
    {
        MidTraversal(T->lchild);
        printf("%d, ", T->data);
        MidTraversal(T->rchild);
    }
}

int main()
{
    int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8};
    AVLTree T = NULL;
    int taller = 0;
    for (int i = 0; i < 10; i++)
    {
        InsertAVLTree(&T, a[i], &taller);
    }
    MidTraversal(T);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值