C++数据结构之AVL树的实现

C++数据结构之AVL树的实现

什么是AVL树

AVL树是一种自平衡二叉查找树,也就是说它通过旋转操作来保持树的平衡。

在AVL树中,任何节点的两个子树高度差不超过1。如果高度差大于1,则需要通过旋转操作来调整树的平衡。

AVL树提供了比红黑树更快的插入和删除操作,但是在读取数据时红黑树更快。

AVL树的实现

结构体定义

我们可以先定义一个结构体来表示AVL树中的节点:

struct Node  
{  
    int value;          // 当前节点的值  
    int height;         // 当前节点的高度  
    Node* left;         // 左子树指针  
    Node* right;        // 右子树指针  

    Node(int v)  
    {  
        value = v;  
        height = 1;  
        left = right = nullptr;  
    }  
};  

在这个结构体中,value表示节点存储的值,height表示当前节点的高度,left和right分别表示左右子树的指针。

插入操作

AVL树的插入操作比较复杂,需要分为以下几个步骤:

  • 向树中插入新节点
  • 更新节点的高度
  • 判断是否需要进行左旋或右旋或LR旋或RL旋操作

我们可以定义一个Insert函数来实现上述操作:

Node* Insert(Node* root, int value)  
{  
    // 向树中插入新节点  
    if (root == nullptr)  
        return new Node(value);  

    if (value < root->value)  
        root->left = Insert(root->left, value);  
    else  
        root->right = Insert(root->right, value);  

    // 更新节点的高度  
    root->height = max(GetHeight(root->left), GetHeight(root->right)) + 1;  

    // 判断是否需要进行左旋或右旋或LR旋或RL旋操作  
    int balance = GetBalance(root);  
    if (balance > 1 && value < root->left->value)  
        return RightRotate(root);  
    if (balance < -1 && value > root->right->value)  
        return LeftRotate(root);  
    if (balance > 1 && value > root->left->value)  
        return LeftRightRotate(root);  
    if (balance < -1 && value < root->right->value)  
        return RightLeftRotate(root);  

    return root;  
}

其中,GetHeight函数用于获取节点的高度,GetBalance函数用于获取节点的平衡因子(左子树高度减去右子树高度)。

LeftRotate、RightRotate、LeftRightRotate、RightLeftRotate分别表示左旋、右旋、LR旋、RL旋操作。

删除操作

AVL树的删除操作也比较复杂,需要分为以下几个步骤:

  • 找到待删除的节点
  • 删除节点
  • 更新祖先节点的高度
  • 判断是否需要进行左旋或右旋或LR旋或RL旋操作

我们可以定义一个Delete函数来实现上述操作:

Node* Delete(Node* root, int value)  
{  
    // 找到待删除的节点  
    if (root == nullptr)  
        return root;  

    if (value < root->value)  
        root->left = Delete(root->left, value);  
    else if (value > root->value)  
        root->right = Delete(root->right, value);  
    else  
    {  
        // 删除节点  
        if (root->left == nullptr || root->right == nullptr)  
            root = (root->left == nullptr ? root->right : root->left);  
        else  
        {  
            Node* cur = root->right;  
            while (cur->left != nullptr)  
                cur = cur->left;  
            root->value = cur->value;  
            root->right = Delete(root->right, cur->value);  
        }  
    }  

    if (root == nullptr)  
        return root;  

    // 更新祖先节点的高度  
    root->height = max(GetHeight(root->left), GetHeight(root->right)) + 1;  

    // 判断是否需要进行左旋或右旋或LR旋或RL旋操作  
    int balance = GetBalance(root);  
    if (balance > 1 && GetBalance(root->left) >= 0)  
        return RightRotate(root);  
    if (balance > 1 && GetBalance(root->left) < 0)  
        return LeftRightRotate(root);  
    if (balance < -1 && GetBalance(root->right) <= 0)  
        return LeftRotate(root);  
    if (balance < -1 && GetBalance(root->right) > 0)  
        return RightLeftRotate(root);  

    return root;  
}

其中,GetHeight函数与Insert函数中一样,GetBalance函数也与Insert函数中一样,LeftRotate、RightRotate、LeftRightRotate、RightLeftRotate也与Insert函数中一样。

示例

我们可以使用以下示例来测试我们实现的AVL树:

int main()  
{  
    Node* root = nullptr;  

    root = Insert(root, 10);  
    root = Insert(root, 20);  
    root = Insert(root, 30);  
    root = Insert(root, 40);  
    root = Insert(root, 50);  
    root = Insert(root, 25);  

    cout << "AVL Tree is:\n";  
    Print(root);  
    cout << endl;  

    root = Delete(root, 50);  

    cout << "AVL Tree after deletion is:\n";  
    Print(root);  
    cout << endl;  

    return 0;  
}  

其中,Print函数用于将AVL树的结构打印出来:

void Print(Node* root)  
{  
    if (root == nullptr)  
        return;  

    cout << root->value << " ";  
    Print(root->left);  
    Print(root->right);  
}  

执行以上程序会得到如下运行结果:

AVL Tree is:
30 20 10 25 40 50
AVL Tree after deletion is:
25 20 10 30 40

从结果可以看出,我们实现的AVL树能够正确地插入和删除节点,并且能够保持树的平衡。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++数据结构之AVL树的实现 - Python技术站

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

相关文章

  • Java数据结构之图的基础概念和数据模型详解

    Java数据结构之图的基础概念和数据模型详解 简介 图是一种非常重要的数据结构,在计算机科学和实际应用中广泛使用。比如搜索引擎中的网页之间的链接关系就可以用图来表示和处理。在本文中,我们将详细讲解图的基础概念和数据模型。同时,我们将通过两个实例来进一步说明图的应用。 图的基础概念 什么是图 图是由若干个节点(顶点)和连接节点的边组成的一种数据结构。一个图可以…

    数据结构 2023年5月17日
    00
  • Java数据结构之加权无向图的设计实现

    Java数据结构之加权无向图的设计实现 前言 在计算机科学中,图(Graph)作为一种基本数据结构,被广泛应用于各种领域,如网络流、图像处理、计算机视觉等。本文将介绍加权无向图(Weighted Undirected Graph)的设计实现,涉及图的存储、添加边、获取特定节点的相邻节点、计算最短路径等。 设计实现 存储结构 加权无向图可以用一个邻接表数组存储…

    数据结构 2023年5月17日
    00
  • Java数据结构的十大排序

    Java数据结构的十大排序攻略 简介 在计算机科学中,排序算法是一种将一串数据按照特定顺序进行排列的方法,其中常见的排序算法有很多种,不同的算法适用于不同的数据类型和数据规模。Java是一种常见的编程语言,也提供了很多实现排序算法的类和方法。 本文将介绍Java数据结构的十大排序算法,分别为:插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序、堆排序…

    数据结构 2023年5月17日
    00
  • Python实现的数据结构与算法之基本搜索详解

    Python实现的数据结构与算法之基本搜索详解 在计算机科学中,搜索指的是在一组数据中找到目标数据的过程。搜索算法是解决各种问题的关键,即使是拼图游戏和图像识别也要依赖搜索算法。本文将介绍基本的搜索算法,包括线性/顺序搜索、二分搜索和广度优先搜索。 线性/顺序搜索 顺序搜索又称为线性搜索,它遍历整个数据集以查找特定元素。顺序搜索可以用于查找未排序的列表。该算…

    数据结构 2023年5月17日
    00
  • C数据结构之双链表详细示例分析

    作为本网站的作者,我很高兴为你讲解C数据结构之双链表详细示例分析的完整攻略。 双链表简介与定义 双链表是链表的一种,在链表中每一个节点都有一个指针域,指向下一个节点,这个指针域称为next指针;而在双链表中每一个节点也有两个指针域,一个指向前驱节点,另一个指向后继节点,即prev指针与next指针。由于双链表存在两个指针域,因此它支持双向遍历,无论是正向还是…

    数据结构 2023年5月17日
    00
  • Java数据结构之堆(优先队列)详解

    Java数据结构之堆(优先队列)详解 概述 堆是一种基于树的数据结构,它可以用来解决很多问题,例如排序、优先队列等。在堆中,每个节点的值都小于或等于它的子节点的值。堆分为两种类型:最大堆和最小堆。在最大堆中,根节点的值最大;而在最小堆中,根节点的值最小。 堆的操作主要有以下两种: 插入:将一个元素插入到堆中,需要维护堆的性质,即节点的值小于或等于子节点的值。…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之单链表的实例详解

    Go语言数据结构之单链表的实例详解 简介 单链表是一个常见的数据结构,它由一系列节点组成,每个节点包含一个值和指向下一个节点的引用。单链表的插入和删除操作比较容易,但是访问操作的效率相对较低。 在Go语言中,可以使用结构体配合指针来实现单链表。 实现思路 为了实现单链表,需要先定义一个节点结构体Node,包含一个value值和一个next指针。通过next指…

    数据结构 2023年5月17日
    00
  • C++数据结构之哈希算法详解

    C++数据结构之哈希算法详解 概述 哈希算法是一种常用于对数据进行快速检索的算法,它通常将数据映射为一个较短的指纹码,并将这个指纹码作为数据的索引值,这样可以快速地根据索引值找到对应的数据。 本文将详细讲解哈希算法的实现原理、常见应用场景以及在 C++ 语言中如何实现一个简单的哈希表。 哈希算法的实现原理 哈希算法的核心思想是将输入数据通过一个哈希函数进行映…

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