C语言 04-树5 Root of AVL Tree

这篇博客介绍了AVL树的基本概念,它是一种自平衡二叉搜索树。文章通过实例展示了在一系列插入操作后如何判断并调整AVL树的平衡状态,包括LL、RR、LR、RL四种旋转规则,以确保树的高度差不超过1。最后,给出了输入输出规格及样例,帮助理解操作过程。

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

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property.
Figures 1-4 illustrate the rotation rules.
这里写图片描述
这里写图片描述
这里写图片描述)
这里写图片描述

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

70

Sample Input 2:

7
88 70 61 96 120 90 65

Sample Output 2:

88

Show me the Code:

#include <stdio.h>
#include <stdlib.h>
#ifndef _AvlTree_H
struct AvlNode;
typedef int ElementType;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;

AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X,AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree T);
AvlTree Delete(ElementType X,AvlTree T);
ElementType Retrieve(Position P);

#endif // _AvlTree_H
#ifndef NULL
#define NULL 0
#endif // NULL
struct AvlNode
{
    ElementType Element;
    AvlTree Left;
    AvlTree Right;
    int Height;
};
int Max(int,int);
static int Height(Position);
AvlTree Insert(ElementType,AvlTree);
AvlTree SingleRotateWithLeft(AvlTree T);
AvlTree SingleRotateWithRight(AvlTree T);
AvlTree DoubleRotateWithLeft(AvlTree T);
AvlTree DoubleRotateWithRight(AvlTree T);

int main()
{
    AvlTree T = NULL;
    int i,N;
    ElementType X;
    scanf("%d",&N);
    for(i=0;i<N;i++)
    {
        scanf("%d",&X);
        T = Insert(X,T);
    }
    printf("%d",T->Element);
}
static int Height(Position P)
{
    if(P == NULL)
    return -1;
    else
    return P->Height;
}
AvlTree Insert(ElementType X, AvlTree T)
{
    if(T == NULL)
    {
    T = (AvlTree)malloc(sizeof(struct AvlNode));
    if(T == NULL)
        printf("Out of space.");
    else
    {
        T->Element = X;
        T->Height = 0;
        T->Left = NULL;
        T->Right = NULL;
    }
    }
    else
    {
    if(X < T->Element)
    {
        T->Left = Insert(X,T->Left);
        if(Height(T->Left)-Height(T->Right) == 2){
        if(X < T->Left->Element)
            T = SingleRotateWithLeft(T);
        else
            T = DoubleRotateWithLeft(T);
        }
    }
    else if(X>T->Element)
    {
        T->Right = Insert(X,T->Right);
        if(Height(T->Right)-Height(T->Left) == 2){
        if(X < T->Right->Element) //第一处不一样
            T = DoubleRotateWithRight(T);
        else
            T = SingleRotateWithRight(T);
        }
    }
    }
    T->Height = Max(Height(T->Left),Height(T->Right)) + 1;
    return T;
}
int Max(int a,int b)
{
    return (a > b) ? a : b;
}

Position SingleRotateWithLeft(Position K2)
{
    Position K1;

    K1 = K2->Left;
    K2->Left = K1->Right;
    K1->Right = K2;

    K2->Height = Max(Height(K2->Left),Height(K2->Right)) + 1;
    K1->Height = Max(Height(K1->Left),Height(K1->Right)) + 1;
    return K1;
}
Position SingleRotateWithRight(Position K2)
{
    Position K1;

    K1 = K2->Right;
    K2->Right = K1->Left;
    K1->Left = K2;

    K2->Height = Max(Height(K2->Left),Height(K2->Right)) + 1;
    K1->Height = Max(Height(K1->Left),Height(K1->Right)) + 1;
    return K1;
}
Position DoubleRotateWithLeft(Position K2)
{
    Position K1, K3;

    K1 = K2->Left;
    K3 = K1->Right;
    K2->Left = K3->Right;
    K1->Right = K3->Left;
    K3->Left = K1;
    K3->Right = K2;

    K1->Height = Max(Height(K1->Left),Height(K1->Right)) + 1;
    K2->Height = Max(Height(K2->Left),Height(K2->Right)) + 1;
    K3->Height = Max(Height(K3->Left),Height(K3->Right)) + 1;
    return K3;
}
Position DoubleRotateWithRight(Position K2)
{
    Position K1, K3;

    K1 = K2->Right;
    K3 = K1->Left;
    K2->Right = K3->Left;
    K1->Left = K3->Right;
    K3->Left = K2;
    K3->Right = K1;

    K1->Height = Max(Height(K1->Left),Height(K1->Right)) + 1;
    K2->Height = Max(Height(K2->Left),Height(K2->Right)) + 1;
    K3->Height = Max(Height(K3->Left),Height(K3->Right)) + 1;
    return K3;
}

运行结果:

这里写图片描述

思路与问题

AVL树的插入和建立过程中,遇到的调整情况分为四类:
1. 麻烦节点出现在左子树的左子树上,此时使用LL变换,将中间的结点变为根节点
2. 麻烦节点出现在右子树的右子树上,此时使用RR变换。。。
3. 麻烦节点出现在左子树的右子树上,这时单边的变换已经没有用了,可以将麻烦节点变为根节点,并调整树向左边增加层数或向右边增加层数。
4. 麻烦节点出现在右子树的左子树上。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值