04-树5 Root of AVL Tree--------C语言

本文详细介绍了AVL树的插入操作及四种旋转调整方法(LL、RR、LR、RL旋转),并通过代码实现了AVL树的平衡维护过程。

摘要生成于 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.

F1.jpg

F2.jpg

F3.jpg

F4.jpg

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

这题主要要弄清楚LL旋转、RR旋转、LR旋转、RL旋转分别是怎么操作,怎么用代码表示:

1、可以看出来,RR旋转是将B的左树连到A的右边,然后B的左树变为A即可,代码为:

Tree single_right_rotation(Tree A)
{
    Tree B=A->right;
    A->right=B->left;
    B->left=A;
    A->height = Max(GetHeight(A->left), GetHeight(A->right))+1;
    B->height = Max(GetHeight(B->left), GetHeight(B->right))+1;
    
    return B;
}

 

2、LL旋转是将B的右子树连到A的左边,B的右子树变为A。代码表示为:

Tree single_left_rotation(Tree A)
{
    Tree B=A->left;
    A->left = B->right;
    B->right=A;
    A->height = Max(GetHeight(A->left), GetHeight(A->right))+1;
    B->height = Max(GetHeight(B->left), GetHeight(B->right))+1;
    
    return B;
}

3、LR旋转看着不太明显,其实可以看成先将B--C这段进行右单旋(图中红色框住的部分),也就是C连上了A,然后B在C的左边;随后,对C----A这段进行左单旋,将C放在了最上面,A在C的右侧。代码实现为:

Tree left_right_rotation(Tree A)
{
    A->left=single_right_rotation(A->left);
    return single_left_rotation(A);
}

 4、RL旋转同理,红色线框中的部分是不是和左单旋非常像。所以先对这部分做左单旋,然后对A----C部分做右单旋。代码实现为:

Tree right_left_rotation(Tree A)
{
    A->right=single_left_rotation(A->right);
    return single_right_rotation(A);

 弄明白了核心原理,接下来就是输出代码了:

这其中有关于左右子树高度的判断代码GetHeight,毕竟想要得到平衡二叉树,首先得知道什么时候不平衡

//04-树5 Root of AVL Tree
#include<stdio.h>
#include<stdlib.h>

struct AVLtree_Node{
    int number;
    struct AVLtree_Node* left;
    struct AVLtree_Node* right;
    int height;
};

typedef struct AVLtree_Node* Tree;

int Max(int a, int b);
int GetHeight(Tree T);
Tree single_left_rotation(Tree A);
Tree single_right_rotation(Tree A);
Tree left_right_rotation(Tree A);
Tree right_left_rotation(Tree A);
Tree NewNode(int Data);
Tree Insert(Tree T, int Data);

int main()
{
    int N=0, i=0, Data=0;
    scanf("%d", &N);
    if(N){
        scanf("%d", &Data);
        Tree T= NewNode(Data);
        for(i=1;i<N;i++){
            scanf("%d", &Data);
            T = Insert(T,Data);
        }
        printf("%d", T->number);
    }
    
    return 0;
}

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

int GetHeight(Tree T)      //关于左右子树高度的判断
{
    int Hl, Hr, MaxH;
    if(T){
        Hl=GetHeight(T->left);
        Hr=GetHeight(T->right);
        MaxH = Max (Hl, Hr);
        return MaxH+1;
    }
    
    else return 0;
}

Tree single_left_rotation(Tree A)
{
    Tree B=A->left;
    A->left = B->right;
    B->right=A;
    A->height = Max(GetHeight(A->left), GetHeight(A->right))+1;
    B->height = Max(GetHeight(B->left), GetHeight(B->right))+1;
    
    return B;
}

Tree single_right_rotation(Tree A)
{
    Tree B=A->right;
    A->right=B->left;
    B->left=A;
    A->height = Max(GetHeight(A->left), GetHeight(A->right))+1;
    B->height = Max(GetHeight(B->left), GetHeight(B->right))+1;
    
    return B;
}

Tree left_right_rotation(Tree A)
{
    A->left=single_right_rotation(A->left);
    return single_left_rotation(A);
}

Tree right_left_rotation(Tree A)
{
    A->right=single_left_rotation(A->right);
    return single_right_rotation(A);
}

Tree NewNode(int Data)
{
    Tree T = (Tree) malloc (sizeof(struct AVLtree_Node)) ;
    T->height=0;
    T->left=T->right=NULL;
    T->number=Data;
    
    return T;
}

Tree Insert(Tree T, int Data)
{
    if(!T) T = NewNode(Data);
    else{
        if(Data>T->number) {
            T->right=Insert(T->right, Data);
            if(GetHeight(T->right)-GetHeight(T->left)==2){   
                if(Data > T->right->number) T=single_right_rotation(T);
                else T=right_left_rotation(T);
            }
        }
        else{
            T->left=Insert(T->left, Data);
            if(GetHeight(T->right)-GetHeight(T->left)==-2){   //平不平衡的判断
                if(Data < T->left->number) T=single_left_rotation(T);
                else T=left_right_rotation(T);
            }
        }
    }
    T->height = Max(GetHeight(T->left), GetHeight(T->right))+1;
    
    return T;
}

 

 

这个错误是由于无法连接到本地主机的10248端口导致的。这个端口通常是kubelet进程监听的端口,用于健康检查。出现这个错误可能是由于kubelet进程没有正确启动或者配置错误导致的。 解决这个问题的方法是检查kubelet进程的状态和配置。你可以按照以下步骤进行操作: 1. 检查kubelet进程是否正在运行。你可以使用以下命令检查kubelet进程的状态: ```shell systemctl status kubelet ``` 如果kubelet进程没有运行,你可以使用以下命令启动它: ```shell systemctl start kubelet ``` 2. 检查kubelet的配置文件。你可以使用以下命令查看kubelet的配置文件路径: ```shell kubelet --kubeconfig /etc/kubernetes/kubelet.conf --config /var/lib/kubelet/config.yaml --bootstrap-kubeconfig /etc/kubernetes/bootstrap-kubelet.conf config view ``` 确保配置文件中的端口号和地址正确,并且与你的环境相匹配。 3. 检查网络连接。你可以使用以下命令检查是否可以连接到localhost10248端口: ```shell curl -sSL http://localhost:10248/healthz ``` 如果无法连接,请确保端口没有被防火墙或其他网络配置阻止。 4. 检查docker的配置。有时候,kubelet进程依赖于docker进程。你可以按照以下步骤检查docker的配置: - 创建/etc/docker目录: ```shell sudo mkdir /etc/docker ``` - 编辑/etc/docker/daemon.json文件,并添加以下内容: ```json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ], "registry-mirrors": ["https://tdhp06eh.mirror.aliyuncs.com"] } ``` - 重启docker进程: ```shell systemctl restart docker ``` 请注意,以上步骤是一种常见的解决方法,但具体解决方法可能因环境而异。如果以上步骤无法解决问题,请提供更多的错误信息和环境配置,以便我们能够更好地帮助你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值