C语言数据结构之平衡二叉树(AVL树)实现方法示例

C语言数据结构之平衡二叉树(AVL树)实现方法示例

介绍

AVL树是一种自平衡二叉搜索树,它保证了所有节点的左右子树高度差不超过1,从而提高了查找、插入和删除操作的效率。本篇文章将介绍如何使用C语言实现AVL树,并提供两个例子以说明实现方法。

实现方法

结构体定义

首先,定义AVL树节点的结构体,包括该节点存储的值、该节点的高度、该节点的左右子树指针。

typedef struct AVLNode {
    int value;
    int height;
    struct AVLNode* left;
    struct AVLNode* right;
} AVLNode;

AVL树的基本操作函数

1. 计算节点高度

计算节点高度的函数可以递归实现,即左右子树高度的最大值加一。如果节点为NULL,其高度为0。

int height(AVLNode* node) {
    if (node == NULL) {
        return 0;
    }
    return 1 + max(height(node -> left), height(node -> right));
}

2. 计算平衡因子

平衡因子是指左子树高度减去右子树高度的差。如果平衡因子的绝对值大于1,则需要进行旋转以保持树的平衡。

int balance_factor(AVLNode* node) {
    if (node == NULL) {
        return 0;
    }
    return height(node -> left) - height(node -> right);
}

3. 左旋转操作

左旋转是指将某个节点的右子树旋转到它的左子树位置,使得该节点成为其右子树的左子树。左旋转需要保持树的平衡性。

AVLNode* left_rotate(AVLNode* node) {
    AVLNode* right_child = node -> right;
    AVLNode* left_subtree = right_child -> left;
    right_child -> left = node;
    node -> right = left_subtree;
    node -> height = max(height(node -> left), height(node -> right)) + 1;
    right_child -> height = max(height(right_child -> left), height(right_child -> right)) + 1;
    return right_child;
}

4. 右旋转操作

右旋转是指将某个节点的左子树旋转到它的右子树位置,使得该节点成为其左子树的右子树。右旋转需要保持树的平衡性。

AVLNode* right_rotate(AVLNode* node) {
    AVLNode* left_child = node -> left;
    AVLNode* right_subtree = left_child -> right;
    left_child -> right = node;
    node -> left = right_subtree;
    node -> height = max(height(node -> left), height(node -> right)) + 1;
    left_child -> height = max(height(left_child -> left), height(left_child -> right)) + 1;
    return left_child;
}

5. 插入操作

插入操作需要找到对应的插入位置,并在插入后保持树的平衡性。首先插入节点,并递归调整其祖先节点的平衡因子,如果平衡因子的绝对值超过1,则进行相应的旋转操作使得树重新平衡。

AVLNode* insert(AVLNode* root, int value) {
    if (root == NULL) {
        AVLNode* new_node = (AVLNode*)malloc(sizeof(AVLNode));
        new_node -> value = value;
        new_node -> height = 1;
        new_node -> left = NULL;
        new_node -> right = NULL;
        return new_node;
    }
    if (value < root -> value) {
        root -> left = insert(root -> left, value);
    } else {
        root -> right = insert(root -> right, value);
    }
    root -> height = max(height(root -> left), height(root -> right)) + 1;
    int bf = balance_factor(root);
    if (bf > 1 && value < root -> left -> value) {
        return right_rotate(root);
    }
    if (bf > 1 && value > root -> left -> value) {
        root -> left = left_rotate(root -> left);
        return right_rotate(root);
    }
    if (bf < -1 && value < root -> right -> value) {
        root -> right = right_rotate(root -> right);
        return left_rotate(root);
    }
    if (bf < -1 && value > root -> right -> value) {
        return left_rotate(root);
    }
    return root; 
}

例子1:插入数字

以下示例代码演示了如何使用上述AVL树的基本操作实现对数字的插入。

AVLNode* root = NULL;
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);

例子2:查找最小节点

除了插入操作外,还可以实现其他操作,例如查找AVL树中的最小节点。以下示例代码演示了如何使用递归实现查找AVL树中的最小节点。

AVLNode* min_node(AVLNode* root) {
    if (root == NULL || root -> left == NULL) {
        return root;
    }
    return min_node(root -> left);
}

总结

本文详细介绍了如何使用C语言实现AVL树的基本操作,包括计算节点高度、计算平衡因子、左旋转、右旋转及插入操作。并通过两个示例演示了如何插入数字及查找AVL树中的最小节点。使用AVL树可以提高二叉搜索树操作的效率,对于需要频繁进行插入、删除操作的数据结构场景来说,尤其有用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之平衡二叉树(AVL树)实现方法示例 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 【ACM算法竞赛日常训练】DAY5题解与分析【储物点的距离】【糖糖别胡说,我真的不是签到题目】| 前缀和 | 思维

    DAY5共2题: 储物点的距离(前缀和) 糖糖别胡说,我真的不是签到题目(multiset,思维) ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验):https://www.eri…

    算法与数据结构 2023年4月18日
    00
  • JS中的算法与数据结构之链表(Linked-list)实例详解

    JS中的算法与数据结构之链表(Linked-list)实例详解 什么是链表? 链表是计算机科学中的一种数据结构,由一系列结点(Link,也称为节点)组成,并通过每个节点中的指针(Pointer)链接在一起。每个节点包含数据和一个指向某个位置的引用。 链表的主要特点是在插入和删除操作中表现出很高的效率。与数组相比,链表的访问和操作速度较慢,但在处理动态结构数据…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结 二叉树是一种非常重要的数据结构,它被广泛应用于算法、数据处理等领域。在Go语言中,使用二叉树可以实现很多高级数据结构和算法。本文将为大家介绍二叉树相关的基本知识和操作,以及如何利用Go语言实现二叉树。 什么是二叉树? 二叉树是一种树形结构,由一个根节点和两个子树组成。它的每个节点最多有两个子节点,称为左子节点和右子节点…

    数据结构 2023年5月17日
    00
  • C语言数据结构深入探索顺序表

    C语言数据结构深入探索顺序表攻略 一、概述 顺序表是一种线性结构,是计算机程序中最常见的数据结构之一。在C语言中,顺序表可以用数组来实现。本篇文章将深入讲解顺序表的原理和实现方法,帮助读者加深对顺序表的理解,并掌握如何用C语言代码实现顺序表。 二、顺序表的定义和特点 顺序表是指用一组地址连续的存储单元依次存储线性表中的各个元素,用于表示具有相同数据类型的n个…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构常见面试问题整理

    JavaScript数据结构常见面试问题整理 介绍 JavaScript是一种广泛使用的脚本语言,用于在Web上创建动态效果,验证表单,增强用户体验等。它是一种高级语言,使用许多数据结构来存储和处理数据。在面试中,考官通常会问一些与JavaScript数据结构相关的问题,这篇文章将整理一些常见的面试问题和他们的解答,以便帮助你做好准备。 常见问题 1. 什么…

    数据结构 2023年5月17日
    00
  • C++线性表深度解析之动态数组与单链表和栈及队列的实现

    C++线性表深度解析之动态数组与单链表和栈及队列的实现 动态数组的实现 动态数组是一种可以动态扩展的数组结构,它的容量可以随着需要而动态增加。在C++中,使用vector类可以实现动态数组的功能。vector类相当于动态分配了一块内存空间,在使用时可以根据需要进行动态扩展。下面是一个示例代码: #include <vector> #include…

    数据结构 2023年5月17日
    00
  • Codeforces Round 871 (Div. 4)

    A.Love Story 题意: 给定n个长度为10的字符串,问其与codeforces字符串的对应下标字母不同的个数。 分析: 对于每个字符串从前往后依次和“codeforces”对应字符比较然后统计不同字母数即可 code: #include <bits/stdc++.h> using namespace std; int main() { …

    算法与数据结构 2023年5月8日
    00
  • C++数据结构之AVL树的实现

    C++数据结构之AVL树的实现 什么是AVL树 AVL树是一种自平衡二叉查找树,也就是说它通过旋转操作来保持树的平衡。 在AVL树中,任何节点的两个子树高度差不超过1。如果高度差大于1,则需要通过旋转操作来调整树的平衡。 AVL树提供了比红黑树更快的插入和删除操作,但是在读取数据时红黑树更快。 AVL树的实现 结构体定义 我们可以先定义一个结构体来表示AVL…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部