C++:priority_queue(优先级队列)的模拟实现

news2024/9/23 7:18:41

目录

一、什么是优先级队列

二、优先级队列的定义

三、优先级队列的常用接口

四、模拟实现一个优先级队列

1、posh接口 

2、empty接口、size接口和top接口

3、pop接口

4、构造函数

五、整体代码


一、什么是优先级队列

        首先优先级队列不是队列,C++ 中的优先队列是STL中的派生容器当你往优先级队列里存放数据的时候,它会像堆一样存放数据,将最大的数据或最小的数据放到前面

(至于什么是堆可以看这篇文章->堆的实现)


二、优先级队列的定义

其中:

T 是数据的类型

Container 是容器类型,vector<T> 是容器;

Compare 是作为仿函数容器,决定了是最大的数据还是最小的数据放在前面。


三、优先级队列的常用接口

empty判断优先级队列是否为空(空返回ture,反之返回false)
size返回优先级队列的数据个数
top返回优先级队列第一个数据
push向优先级队列添加数据
pop删除优先级队列中的数据
swap交换两个优先级队列里的数据

四、模拟实现一个优先级队列

        (以大堆为例)

        我们要实现一个优先级队列,最开始要搭建好它的底层。

template <class T, class Container = vector<T>, class Compare = less<T> >
class priority_queue
{
public:

private:
    Container c;
    Compare comp;
};

vector<T> 作为容器(或者其它)构建一个自变c同理用 liss<T>作为容器,构建仿函数comp

因为优先级队列会像堆一样存放数据,所以实现优先级队列基本就是实现一个堆。


1、posh接口 

  • 若我们向一个堆里存放数据后,需要向上调整,所以需要一个向上调整数据的函数 adjust_up()

 (注:在标准库里有adjust_up()函数,但我们是要自己完成一个)

void adjust_up(int child)
{
    int parent = (child - 1) / 2;

    while (child > 0)
    {
        if (c[parent] < c[child])
        {
            swap(c[parent], c[child]);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}

但这个代码不够好,(事先说明下面还有一个向下调整函数)若我们想用小堆嘞?总不可能要在类里一个个改它们的比较方式吧,这时候仿函数就该英雄出场了。

if (c[parent] < c[child]) -> if (comp(c[parent], c[child]))

将if中的判断改为函数判断的形式,我们只需在判断函数里修改即可。 

所以push接口可以写成这样↓

void push(const T& x)
{
    c.push_back(x);
    adjust_up(c.size() - 1);
}

2、empty接口、size接口和top接口

因为我们借用了vector作为容器,所以我们可以使用它的接口来代替优先级队列的接口。

bool empty() const
{
    return c.empty();
}

size_t size() const
{
    return c.size();
}

size_t size() const
{
    return c.size();
}

3、pop接口

当我们要删除数据的时候删堆顶的数据,要将堆顶的数据和堆最后的数据互换,然后在利用容器的接口来删除数据。

void pop()
{
    swap(c[0],c[c.size() - 1]);
    c.pop_back();
    adjush_dowm();
}
  • 这里我们需要利用向下调整函数adjust_down()将优先级队列重新排好序。 
void adjush_dowm()
{
    int parent = 0;
    int child = parent * 2 + 1;

    while (child < c.size())
    {
        if (child + 1 < c.size() && comp(c[child], c[child + 1]))
        {
            child++;
        }

        if (comp(c[parent], c[child]))
        {
            swap(c[parent], c[child]);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}

 这样我们的优先级队列的大部分接口就实现了。现在我们还差它的构造函数了。


4、构造函数

priority_queue() {};
//利用迭代器来构造优先级队列
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
    InputIterator it = first;
    while (it != last)
    {
        push(*it);
        it++;
    }
}

五、整体代码

template <class T, class Container = vector<T>, class Compare = less<T> >
class priority_queue
{
public:
    priority_queue() {};
    template <class InputIterator>
    priority_queue(InputIterator first, InputIterator last)
    {
        InputIterator it = first;
        while (it != last)
        {
            push(*it);
            it++;
        }
    }

    void adjust_up(int child)
    {
        int parent = (child - 1) / 2;

        while (child > 0)
        {
            if (comp(c[parent], c[child]))
            {
                swap(c[parent], c[child]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
                break;
        }
    }

    void push(const T& x)
    {
        c.push_back(x);
        adjust_up(c.size() - 1);
    }

    bool empty() const
    {
        return c.empty();
    }

    size_t size() const
    {
        return c.size();
    }

    const T& top() const
    {
        return c[0];
    }

    void adjush_dowm()
    {
        int parent = 0;
        int child = parent * 2 + 1;

        while (child < c.size())
        {
            if (child + 1 < c.size() && comp(c[child], c[child + 1]))
            {
                child++;
            }

            if (comp(c[parent], c[child]))
            {
                swap(c[parent], c[child]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
                break;
        }
    }

    void pop()
    {
        swap(c[0],c[c.size() - 1]);
        c.pop_back();
        adjush_dowm();
    }

    private:
        Container c;
        Compare comp;
    };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2117342.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IP包头的总长度字段和UDP包头的长度字段之间的关系

IP包头的总长度字段和UDP包头的长度字段之间的关系&#xff0c;并通过实例加以说明。 IP包头的总长度字段 **总长度&#xff08;Total Length&#xff09;**字段是一个16位的字段&#xff0c;表示整个IP数据包的总长度&#xff0c;包括IP包头和数据部分。单位是字节。由于该字…

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人&#xff0c;是不是经常需要制作各种PPT来分享我的生活和想法。但是&#xff0c;你们知道&#xff0c;有时候灵感来了&#xff0c;时间却不够用了&#xff01;&#x1f629;直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手&#…

PID控制算法(二)

&#xff08;BIlibili借鉴&#xff09;PID参数整定连接&#xff1a;Webpack App (rossning92.github.io) C的基本程序代码&#xff1a; 借鉴链接&#xff1a;PID超详细教程——PID原理串级PIDC代码在线仿真调参-CSDN博客 #include <iostream>using namespace std;stru…

【信创】统信UOS桌面UT-2024-0027漏洞修复

原文链接&#xff1a;【信创】统信UOS系统UT-2024-0027漏洞修复 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于统信UOS桌面操作系统UT-2024-0027漏洞修复的文章。漏洞修复是确保系统安全性的重要步骤&#xff0c;及时更新和修复系统中的安全漏洞&#xff0c;可…

大数据之Flink(三)

9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…

Go开源日志库Logrus的使用

一、Logrus简介 Logrus 是一个流行的 Go 语言日志库&#xff0c;以其功能强大、性能高效和高度灵活性而闻名。有关更多介绍可查看 Logrus。 主要特点 丰富的日志级别&#xff1a;Logrus 支持多种日志级别&#xff0c;包括 Debug、Info、Warn、Error、Fatal 和 Panic&#xf…

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中&#xff0c; "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时&#xff0c;经常听到第一范式&#xff08;1NF&#xff09;、第二范式&#xff08;2NF&#xff09;、第三范式&#xff08;3NF&#xff09;以及 BCNF&#xff08;Boyce-…

RESTful 还是 JSON-RPC

前言 RESTful 比较简单地说就是&#xff0c;大家请求一样的url&#xff08;GET方法有一个例外&#xff0c;url中带了一个id&#xff09;&#xff0c;通过不同的请求方法&#xff0c;分别进行不同的操作&#xff08;CRUD&#xff09;。 JSON-RPC JSON-RPC是一个无状态且轻量级…

SpringBoot学习(7)(Bean对象注册)(自定义组合注解)

目录 一、引言 二、案例学习 &#xff08;一&#xff09;Bean &#xff08;二&#xff09;Import 三、补充 &#xff08;1&#xff09;关于Java中collection.toArray(new String[0])解释 &#xff08;2&#xff09;组合注解 一、引言 上次学习了解到&#xff0c;springb…

基于机器学习的阿尔兹海默症智能分析预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 阿尔兹海默症&#xff08;Alzheimers Disease, AD&#xff09;是一种常见的神经退行性疾病&#xff0c;主要影响老年人的认知功能。随着全球人口老龄化的加剧&#xff0c;阿尔兹海默症的患病率逐年…

nodejs 使用kafka案例,node-red配置kafka案例,从安装配置kafka开始

生产者测试&#xff1a; bin/kafka-console-producer.sh --broker-list 1.2.3.4:9092 --topic test-topic消费者测试&#xff1a; bin/kafka-console-consumer.sh --bootstrap-server 1.2.3.4:9092 --topic test-topic --from-beginningconst { Kafka } require(kafkajs)con…

【AIGC数字人】EchoMimic:基于可编辑关键点条件的类人音频驱动肖像动画

GitHub&#xff1a;https://github.com/BadToBest/EchoMimic 论文&#xff1a; https://arxiv.org/pdf/2407.08136 comfyui&#xff1a; https://github.com/smthemex/ComfyUI_EchoMimic 相关工作 Wav2Lip Wav2Lip是一个开创性的工作 &#xff0c;但输出会出现面部模糊或扭…

粒子群算法原理的示例介绍

一&#xff1a;粒子群优化算法的介绍 粒子群优化算法&#xff08;PSO&#xff09;是一种基于群体智能的优化算法&#xff0c;于1995年提出。它受到鸟群狩猎行为的启发&#xff0c;通过模拟鸟群或鱼群的社会行为来进行问题的求解。 基本原理 粒子群算法中&#xff0c;每个解决…

顶刊算法 | Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测,优化前后对比

顶刊算法 | Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测&#xff0c;优化前后对比 目录 顶刊算法 | Matlab实现鹈鹕算法POA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测&#xff0c;优化前后对比预测效果基本介绍…

一种小众且适合发文的智能优化算法应用——三维TSP问题

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 今天给大家介绍一种非常小众的智能优化算法应用&am…

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大&#xff0c;但不同的语言在不同领域都有着自己的优势&#xff0c;为了强强联合&#xff0c;LabVIEW提供了强大的外部程序接口能力&#xff0c;包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等…

2024/9/9 408“回头看”:

B树是什么&#xff1f;有什么作用&#xff1f;B树的插入和删除具体细节是什么&#xff1f;除了B树还有一个是B&#xff0b;树、还是B-树&#xff0c;他们有什么区别&#xff0c;又有什么相同点&#xff1f; b树在王道考研查找这一章&#xff0c;所以他的主要作用就是查找。 在…

MySQL中binary放在判断语句之前有什么作用

为什么要加binary进行判断 ① 因为 mysql中等号比较是不区分大小写的&#xff0c;select aA这个输出结果为1。 ② 在判断语句之前 加上binary可以以区分大小写比较 &#xff0c;因为这样底层会用二进制形式比较&#xff0c;实现精确匹配。 代码比较 忽略大小写比较 select …

Ftrans跨域文件传输方案,数据流动无阻的高效路径

大型集团企业由于其规模庞大、业务广泛且往往将分支机构、办事处分布在多个地域&#xff0c;因此会涉及到跨域文件传输的需求。主要源于以下几个方面&#xff1a; 1.业务协同&#xff1a;集团内部的不同部门或子公司可能位于不同的地理位置&#xff0c;但需要进行紧密的业务协…

【C++】STL学习——priority_queue(了解仿函数)

目录 priority_queue介绍迭代器种类priority_queue实现仿函数仿函数的使用 priority_queue介绍 优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。此上下文类似于堆&#xff0c;在堆中可以随时插入元素&#x…