1.堆介绍

「堆 heap」是一种满足特定条件的完全二叉树,主要可分为图 8-1 所示的两种类型。

  • 「大顶堆 max heap」:任意节点的值

    其子节点的值。
  • 「小顶堆 min heap」:任意节点的值

    其子节点的值。

堆作为完全二叉树的一个特例,具有以下特性。

最底层节点靠左填充,其他层的节点都被填满。

我们将二叉树的根节点称为“堆顶”,将底层最靠右的节点称为“堆底”。

对于大顶堆(小顶堆),堆顶元素(即根节点)的值分别是最大(最小)的。

2.使用优先级队列(priority_queue)创建和维护堆

2.1 概念

堆(heaps) 是一种特殊的数据组织方式,STL 中的 priority_queue 容器适配器底层就是采用堆来组织数据存储的。

实际上,堆通常用作实现优先队列,大顶堆相当于元素按从大到小顺序出队的优先队列。从使用角度来看,我们可以将“优先队列”和“堆”看作等价的数据结构。因此,这里对两者不做特别区分,统一使用“堆“来命名。

2.2 实例

C++标准库中的 std::priority_queue 是一种用于创建和维护堆的容器适配器。它提供了一种方便的方式来实现堆数据结构,通常用于处理具有优先级的元素。以下是使用 std::priority_queue 来创建和维护堆的使用介绍:

  1. 包含头文件

    #include <queue>
  2. 创建优先队列

    std::priority_queue<int> maxHeap; // 创建一个最大堆,默认情况下是最大堆
    std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap; // 创建一个最小堆
    std::priority_queue <int,vector<int>,less<int> > maxHeap;//创建一个最大堆
    • 你可以创建一个最大堆(默认情况),或者通过提供第二个参数为 std::vector 和第三个参数为 std::greater 来创建一个最小堆。
  3. 插入元素

    使用 push 方法将元素插入堆中,堆会自动维护其性质。

    maxHeap.push(10);
    minHeap.push(5);
  4. 访问堆顶元素

    使用 top 方法可以访问堆顶元素,即最大值(最大堆)或最小值(最小堆)。

    int max = maxHeap.top();
    int min = minHeap.top();
  5. 移除堆顶元素

    使用 pop 方法可以移除堆顶元素,堆会自动维护其性质

    maxHeap.pop(); // 移除最大堆顶元素
    minHeap.pop(); // 移除最小堆顶元素
  6. 检查堆是否为空

    使用 empty 方法可以检查堆是否为空。

    bool isMaxHeapEmpty = maxHeap.empty();
    bool isMinHeapEmpty = minHeap.empty();
  7. 获取堆中元素的数量

    使用 size 方法可以获取堆中元素的数量。

    int maxHeapSize = maxHeap.size();
    int minHeapSize = minHeap.size();
  8. 自定义比较函数

    如果你需要自定义比较函数来定义元素之间的比较规则,可以在创建优先队列时提供自定义比较函数。

    struct Compare {
    bool operator()(int a, int b) {
    // 自定义比较规则
    return a > b; // 创建最小堆
    }
    }; std::priority_queue<int, std::vector<int>, Compare> customHeap;

    在上述例子中,我们创建了一个自定义的比较函数 Compare,它定义了创建一个最小堆。

std::priority_queue 简化了堆的创建和维护,特别适用于需要按优先级访问元素的问题,如任务调度、Dijkstra算法等。你可以根据问题的要求选择最大堆或最小堆,并通过提供自定义比较函数来实现更复杂的比较规则。

3.使用make_heap等系列函数创建和维护堆

3.1 概念

在C++中,make_heappush_heappop_heapsort_heap 是用于操作堆的四个标准库算法。这些算法用于处理堆数据结构,它们可以帮助你创建、维护和排序堆。以下是它们的用途和用法:

3.2 具体函数

  1. make_heap:([]中内容可省略)

    • 用途:make_heap 用于将一个范围内的元素转化为一个堆,默认是大顶堆(通常是最大堆或最小堆)。
    • 语法:make_heap(first, last,[less<>()/greater<>()]):([]中内容可省略)),其中 firstlast 分别是范围的起始迭代器和结束迭代器。

      其中第三个参数是less<>()或是greater<>(),前者用于生成大顶堆,后者用于生成小顶堆,第三个参数默认情况下为less<>(),less()用于生成大顶堆。
    • 示例:
    vector<int> nums = {3, 1, 4, 1, 5, 9, 2};
    display(nums);
    make_heap(nums.begin(), nums.end());
    display(nums);
    // nums 现在是一个最大堆,最大值 9 在根节点
    结果:
    (原数组)3 1 4 1 5 9 2
    (现数组)9 5 4 1 1 3 2
  2. push_heap

    • 用途:push_heap 用于将新元素添加到堆中,同时维护堆的性质。(确保已有的元素序列是一个有效的堆,否则请先使用make_heap创建堆)
    • 语法:push_heap(first, last,[less<>()/greater<>()]),其中 firstlast 定义了一个范围,范围内的元素是一个堆,且在 firstlast - 1 之间添加了一个新元素。第三个参数同上。
    • 示例:
    vector<int> nums = {3, 1, 4, 1, 5};
    display(nums);
    make_heap(nums.begin(), nums.end());
    display(nums);
    nums.push_back(9);
    push_heap(nums.begin(), nums.end());
    display(nums);
    // nums 现在是一个最大堆,最大值 9 在根节点 结果:
    3 1 4 1 5(原先)
    5 3 4 1 1(建堆后)
    9 3 5 1 1 4(插入新元素后)
  3. pop_heap

    • 用途:pop_heap 用于将(确保已有的元素序列是一个有效的堆,否则请先使用make_heap创建堆)的根节点(通常是最大值或最小值)取出,并将其放在范围的末尾,然后维护剩余元素的堆性质(对前n - 1个元素调用make_heap()函数)。
    • 语法:pop_heap(first, last,[less<>()/greater<>()]),其中 firstlast 定义了一个范围,范围内的元素是一个堆。第三个参数同上
    • 示例:
    vector<int> nums = {9, 1, 4, 1, 5};
    display(nums);
    make_heap(nums.begin(), nums.end());
    display(nums);
    pop_heap(nums.begin(), nums.end());
    display(nums);
    // nums 现在是一个最大堆,最大值 9 被移至范围末尾
    结果展示:
    9 1 4 1 5(原先)
    9 5 4 1 1(建堆后)
    5 1 4 1 9(移出一个元素出堆,注意这里的9只是移到了最后,并没有去除)
  4. sort_heap

    • 用途:sort_heap 用于对一个(确保已有的元素序列是一个有效的堆,否则请先使用make_heap创建堆)进行排序,将堆中的所有元素按升序排列(小根堆)。
    • 语法:sort_heap(first, last,,[less<>()/greater<>()]),其中 firstlast 定义了一个范围,范围内的元素是一个堆。第三个参数同上。
    • 示例:
    vector<int> nums = {9, 1, 4, 1, 5};
    display(nums);
    make_heap(nums.begin(), nums.end());
    display(nums);
    sort_heap(nums.begin(), nums.end());
    display(nums); 结果展示:
    9 1 4 1 5(原先)
    9 5 4 1 1(建堆后)
    1 1 4 5 9(排序后)

这些堆算法对于处理堆数据结构非常有用,可以在各种算法和数据结构中使用。堆通常用于实现优先队列和解决一些最大值或最小值相关的问题。这些算法可以提高代码的可读性和效率,因为它们是经过精心设计和优化的标准库函数。

4.二者的区别和各自的优势

4.1 优先级队列优势

priority_queue 可以提供堆没有的优势,它可以自动保持元素的顺序;但我们不能打乱 priority_queue的有序状态,因为除了第一个元素,我们无法直接访问它的其他元素。如果需要的是一个优先级队列,这一点非常有用。

4.2 使用 make_heap()优势

从另一方面来说,使用 make_heap() 创建的堆可以提供一些 priority_queue 没有的优势:

1、可以访问堆中的任意元素,而不限于最大的元素,因为元素被存储在一个容器中,就像是我们自己的 vector。这也提供了偶然破坏元素顺序的可能,但是总可以调用 make_heap()来还原堆。

2、可以在任何提供随机访问迭代器的序列容器中创建堆。这些序列容器包括普通数组、string 对象、自定义容器。这意味着无论什么时候需要,都可以用这些序列容器的元素创建堆,必要时,可以反复创建。甚至还可以为元素的子集创建堆。

C++ 语法结构--堆的更多相关文章

  1. Linux程序存储结构与进程结构堆和栈的区别【转】

    转自:http://www.hongkevip.com/caozuoxitong/Unix_Linux/24581.html 红客VIP(http://www.hongkevip.com):Linux ...

  2. 04 Linux 指令语法结构与帮助命令

    一.Linux指令语法结构 [tyang3@localhost Desktop]$ command [-options] [arguments] 指令           选项           参 ...

  3. CSS_简介/语法结构/长度单位/应用方式/标签的样式重置/表单样式重置

    一.CSS简介:  w3c(World Wide Web Consortium):万维网联盟,是规定网页标准的一个组织(叫做Web标准) Web标准:是由w3c和其他标准化组织制定的一系列标准的集合, ...

  4. PHP读书笔记(1)-PHP语法结构与变量

    一 .php基础语法 1.php语法结构 标准风格:<?php code; ?>.PHP每句代码用;(分号)结尾.<---就用这个,其他的看看就可以了 短风格:<? code; ...

  5. C#中区别多态、重载、重写的概念和语法结构

    C#中区别多态.重载.重写的概念和语法结构 重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override. 格式: 基类中: public virtual ...

  6. Java初认识--Java中的语法结构

    Java中的语法结构(程序流程控制) Java的语法结构有四种: 1.顺序结构. 顺序结构很简单,就是按顺序执行,输出就可以了. 2.判断结构. 判断结构的一个代表性的语句是if:if语句有三种格式体 ...

  7. Tcl与Design Compiler (二)——DC综合与Tcl语法结构概述

    1.逻辑综合的概述 synthesis = translation + logic optimization + gate mapping . DC工作流程主要分为这三步 Translation : ...

  8. html dl dt dd标签元素语法结构与使用

    dl dt dd认识及dl dt dd使用方法 标签用于定义列表类型标签. dl dt dd目录 dl dt dd介绍 结构语法 dl dt dd案例 dl dt dd总结 一.dl dt dd认识 ...

  9. PHP基本的语法结构

    学过C语言的话,上手PHP语言就非常快了,如果你有bash shell的基础,那恭喜你,上手PHP会更快,我们先来了解一下一些比较简单的东西,界定符和注释在PHP中的写法: 一 php文档的语法结构 ...

  10. Shader的基本用法和语法结构

    Shader的基本用法和语法结构 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Introductio ...

随机推荐

  1. 华企盾DSC控制台+系统运维模块连接不上问题

    解决方法:把rundll32.exe进程结束之后再点系统运维模块

  2. 解决 VM with version 2.1.0 has multidex support ; VM has multidex support, MultiDex support library is disabled.问题

    发布打包完之后,android studio提示 VM with version 2.1.0 has multidex support I/MultiDex: installI/MultiDex: V ...

  3. 技本功|Hive优化之建表配置参数调优(一)

    简介: Hive是大数据领域常用的组件之一,主要用于大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的一个点,因此掌握一些Hive调优是必不可少的一项技能.影响Hive效率的主 ...

  4. zabbix 默认消息

    故障事件: {TRIGGER.NAME}监控状态: {TRIGGER.STATUS}报警严重性: {TRIGGER.SEVERITY}触发结果: {TRIGGER.URL}告警时间:{EVENT.DA ...

  5. JavaFx 打包jar(六)

    JavaFx 打包jar(六) JavaFX 从入门入门到入土系列 我们编写了不少javafx,那么如何打包成jar给用户呢?下面我给出比较全的打包方式. 打包jar 下面我给出比较全的打包方式. 1 ...

  6. JVM优化:如何进行JVM调优,JVM调优参数有哪些

    Java虚拟机(JVM)是Java应用运行的核心环境.JVM的性能优化对于提高应用性能.减少资源消耗和提升系统稳定性至关重要.本文将深入探讨JVM的调优方法和相关参数,以帮助开发者和系统管理员有效地优 ...

  7. Underlay网络:如何立住可靠又支持大规模无收敛的“人设”

    摘要:Underlay网络要如何演进,才能满足5个9的指标? 这几年公有云业务急速上涨,network as a service理念越来越深入人心.云厂商给租户提供了越来越丰富的云服务,VPC.LB等 ...

  8. 云小课|MRS基础操作之配置DataNode容量均衡

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:当HDFS集群出现 ...

  9. 将模型转为NNIE框架支持的wk模型第一步:tensorflow->caffe

    摘要:本系列文章旨在分享tensorflow->onnx->Caffe->wk模型转换流程,主要针对的是HI3516CV500, Hi3519AV100 支持NNIE推理框架的海思芯 ...

  10. 云图说丨OLAP开源引擎的一匹黑马,MRS集群组件之ClickHouse

    摘要:ClickHouse是俄罗斯公司 Yandex 在2016年开源的高性能.开源联机分析列式数据库管理系统.开源后,凭借卓越的分析性能.极好的线性扩展能力和丰富的功能,被业界公认为实时分析领域 O ...