首页 > 其他分享 >大根堆和小根堆的介绍

大根堆和小根堆的介绍

时间:2024-08-05 15:27:28浏览次数:9  
标签:std 大根堆 介绍 根堆 queue push minHeap 节点 priority

堆(Heap)的基本概念

堆是一种完全二叉树(Complete Binary Tree),其性质使得堆可以高效地支持以下操作:

  • 插入(Insert):将一个新元素加入到堆中。
  • 删除最大/最小元素(Delete Max/Min):移除并返回堆中的最大(大根堆)或最小(小根堆)元素。
  • 获取最大/最小元素(Get Max/Min):返回堆中的最大(大根堆)或最小(小根堆)元素。

大根堆(Max-Heap)

特性

  • 每个节点的值都大于或等于其子节点的值。
  • 根节点是堆中最大的元素。

插入操作

  1. 将新元素插入到树的最底层的最后位置(保持完全二叉树的性质)。
  2. 进行“上浮”操作,将新元素逐步与其父节点交换,直到堆的性质恢复或到达根节点为止。

删除最大元素

  1. 移除根节点。
  2. 将最后一个元素移动到根位置。
  3. 进行“下沉”操作,将根节点逐步与其较大的子节点交换,直到堆的性质恢复或到达叶子节点为止。

小根堆(Min-Heap)

特性

  • 每个节点的值都小于或等于其子节点的值。
  • 根节点是堆中最小的元素。

插入操作

  1. 将新元素插入到树的最底层的最后位置(保持完全二叉树的性质)。
  2. 进行“上浮”操作,将新元素逐步与其父节点交换,直到堆的性质恢复或到达根节点为止。

删除最小元素

  1. 移除根节点。
  2. 将最后一个元素移动到根位置。
  3. 进行“下沉”操作,将根节点逐步与其较小的子节点交换,直到堆的性质恢复或到达叶子节点为止。

C++ 示例代码

以下是详细的 C++ 示例代码,展示如何实现大根堆和小根堆:

#include <iostream>
//在c++中,使用优先队列需要包含queue这个头文件
#include <queue>
#include <vector>

// 大根堆(默认行为)
void maxHeapExample() {
    // 创建一个大根堆
    std::priority_queue<int> maxHeap;

    // 插入元素
    maxHeap.push(10);
    maxHeap.push(20);
    maxHeap.push(5);
    maxHeap.push(15);

    std::cout << "Max-Heap (大根堆): ";
    // 输出并删除堆顶元素
    while (!maxHeap.empty()) {
        std::cout << maxHeap.top() << " "; // 获取堆顶元素
        maxHeap.pop(); // 删除堆顶元素
    }
    std::cout << std::endl;
}

// 小根堆
void minHeapExample() {
    // 自定义比较函数,逆序(大根堆),实现小根堆
    auto cmp = [](int left, int right) { return left > right; };
    std::priority_queue<int, std::vector<int>, decltype(cmp)> minHeap(cmp);

    // 插入元素
    minHeap.push(10);
    minHeap.push(20);
    minHeap.push(5);
    minHeap.push(15);

    std::cout << "Min-Heap (小根堆): ";
    // 输出并删除堆顶元素
    while (!minHeap.empty()) {
        std::cout << minHeap.top() << " "; // 获取堆顶元素
        minHeap.pop(); // 删除堆顶元素
    }
    std::cout << std::endl;
}

int main() {
    maxHeapExample();
    minHeapExample();

    return 0;
}

代码解释

  1. 大根堆(Max-Heap)
    • std::priority_queue<int> 默认是大根堆。priority_queue 是 STL 提供的容器适配器,基于堆实现。
    • 插入元素使用 push(),获取堆顶元素使用 top(),删除堆顶元素使用 pop()
  2. 小根堆(Min-Heap)
    • 通过自定义比较函数来实现小根堆。std::priority_queue 的构造函数允许传递自定义的比较函数。
    • auto cmp = [](int left, int right) { return left > right; }; 是一个 lambda 表达式,用于将小根堆的比较函数定义为 left > right
    • 构造 priority_queue 时,传递 cmp 作为比较函数,这样就会形成小根堆。

小根堆的实现细节与第二种实现方式

在 C++ 的 priority_queue 中,如果你不显式地提供第二个模板参数(即底层容器类型),它会默认使用 std::vector 作为底层容器。这意味着,你可以只指定元素类型和比较函数(或者不指定比较函数,使用默认的比较方式),而不必显式地指定底层容器类型。

示例:

#include <iostream>
#include <queue>

struct Compare {
    bool operator()(int left, int right) {
        // 小根堆的比较规则:左边的值小于右边的值返回 true
        return left > right;
    }
};

void minHeapExample() {
    // 不显式指定底层容器类型,仍然会使用默认的 std::vector<int>
    std::priority_queue<int, std::vector<int>, Compare> minHeap;

    // 插入元素
    minHeap.push(10);
    minHeap.push(20);
    minHeap.push(5);
    minHeap.push(15);

    std::cout << "Min-Heap (小根堆): ";

    // 输出并删除堆顶元素
    while (!minHeap.empty()) {
        std::cout << minHeap.top() << " "; // 获取堆顶元素
        minHeap.pop(); // 删除堆顶元素
    }
    std::cout << std::endl;
}

int main() {
    minHeapExample();

    return 0;
}

解释:

  • std::priority_queue<int, std::vector<int>, Compare> minHeap; 中,我们没有显式地提供第二个模板参数(底层容器类型),因此默认使用 std::vector<int>
  • 这样做的好处是简化了代码,使其更具可读性,并且仍然能够正常使用小根堆的功能。
  • 如果你想要使用除了 std::vector 以外的其他底层容器,你可以显式地指定第二个模板参数,例如 std::deque<int> 或者其他适合的容器类型。

因此,答案是:可以不显式提供第二个模板参数 std::vector<int>priority_queue 能够识别到并使用默认的 std::vector 作为底层容器类型。

标签:std,大根堆,介绍,根堆,queue,push,minHeap,节点,priority
From: https://www.cnblogs.com/Tomorrowland/p/18343313

相关文章

  • 介绍微软的三款工具,增加你的开发效率
    1、PowerToys它最实用的就是1、获取电脑颜色拾取器,尺寸大小测量,这个对前端或者UI方便2、直接快速打开环境变量、Host、注册表3、对桌面进行布局4、通常我们进行大容量的文件复制比如从盘符复制东西到U盘,已经关闭文件资源管理器,但是弹出U盘时依然报错使用它,右键直接解锁2、......
  • 关于比特率与波特率的定义与区别介绍
    比特率(BitRate)和波特率(BaudRate)是数字通信中两个重要的概念,它们分别用于衡量数字信号的传输速率和信号变化的次数。以下是对比特率和波特率的详细解析:比特率(BitRate)比特率的定义:比特率是指单位时间内传输或处理的比特(bit)的数量,通常以“比特每秒”(bit/s或bps)为单位。在电信和......
  • AI绘画工具介绍
    AI绘画工具是利用人工智能技术进行绘画创作的工具,近年来随着人工智能技术的发展,AI绘画已经成为一个独立的领域,并且在艺术、设计等多个领域得到了广泛应用。以下是一些常见的AI绘画工具介绍:1.StableDiffusion(SD)简介:StableDiffusion是一种基于深度学习的文本到图像生成模型,......
  • pinecone向量库的介绍和基本使用(增删改查)
    本文来自于【向量库】pinecone向量库的介绍和基本使用(增删改查)Pinecone是一个实时、高性能的向量数据库,专为大规模向量集的高效索引和检索而设计。它提供亚秒级的查询响应时间,确保用户可以迅速获取所需信息。Pinecone采用高度可伸缩的分布式架构,可以轻松应对不断增长的数......
  • JS中常用的工具汇总及简单介绍1
    一、数组工具1、push(参数1...[参数n]):向数组末尾添加数据2、pop(无参):向数组末尾删除数据3、unshift(参数1...[参数n]):向数组前方添加数据4、shift(无参):向数组删除添加数据5、splice(开始位置,删除几个):数组数据的截取,被截取的数据会被删除6、reverse(无参数)......
  • JS中常用的事件汇总及简单介绍
    1、BOM常用事件1)window.onload=函数名:当浏览器中的所有结构都被加载完了,才会执行2)window.onscroll=函数名:当页面滚动条发生滚动的时候会触发事件3)window.onresize函数名:在页面尺寸发生改变时,触发的事件2、input输入框事件1)onblur:输入框失去焦点会触发这个事件示例:<input......
  • 【pkill & pgrep】Centos/Linux pkill命令详细介绍
    简介        系统版本:Centos7.6    pkill命令用于杀死一个进程,会根据进程名称和其他属性杀死进程(默认会向进程发送SIGTERM信号,详细请看Linux信号的行为说明),与之相似的命令有killall,与kill命令相比,kill命令需要ps命令的配合查出PID,而pkill命令可以直接根据进......
  • 帝国CMS网站/e/ 系统程序目录结构介绍
    /e/系统程序目录  ├action/    信息动态列表页和内容页目录  ├admin/      后台目录 (可重命名)  ├class/      系统核心文件目录  ├data/      系统处理数据相关目录 (临时文件、缓存等)  ├DoInfo/    前台......
  • Jenkins产介绍
    Jenkins介绍Jenkins是一款流行的开源持续集成(ContinuousIntegration)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能,官网:https://www.jenkins.io/zh/。Jenkins的特征:开源的Java语言开发持续集成工具,支持持续集成,持续部署。易于安装部署配置:可通过yum安装或下载war包......
  • MySQL的索引详细介绍(全网最详细!!!)
    目录1.什么是索引1.1索引的数据结构1.1.1Hash表1.1.2二叉查找树1.1.3平衡二叉树1.1.4B树1.1.5B+树2.索引的优缺点3.索引的使用场景4.索引的分类4.1主键索引4.2唯一索引4.3单值索引(单列索引)4.4复合索引(组合索引)4.5普通索引4.6全文索引4.7空间索引4.8......