【C++】优先队列

news2025/1/4 19:02:09

优先队结构的不同物理结构与常用操作算法

优先队列是一种特殊的队列,队列中的元素具有优先级,每次弹出操作会弹出优先级最高的元素。

优先队列常用的物理结构有:

1. 数组:简单但不高效,插入和删除操作需要移动大量元素,时间复杂度高。

2. 二叉堆:是一种完全二叉树,通常用数组表示。插入和删除操作时间复杂度为O(logn)

3. 二叉搜索树:节点值大于左子树所有节点,小于右子树所有节点。插入和删除操作时间复杂度取决于树的高度,平衡二叉搜索树时间复杂度为O(logn)

常用操作设计:

1. 插入元素:将新元素插入到合适的位置,维持堆的性质。

2. 删除最大/最小元素:删除根节点元素,并调整堆的结构。

3. 获取最大/最小元素:直接返回堆顶元素。

4. 堆大小:返回堆中的元素个数。

5. 堆空:判断堆是否为空。

使用数组结构实现最小堆的代码:

#include <iostream>

using namespace std;

template <typename T>
class PriorityQueue
{
private:
    T *arr;
    int capacity;
    int size;

public:
    PriorityQueue(int cap)  //创造队列
    {
        capacity = cap;
        size = 0;
        arr = new T[cap];
    }

    int getSize()
    {
        return size;
    }

    bool isEmpty()
    {
        return size == 0;
    }

    void insert(T elem)
    {
        if (size == capacity)
        {
            return;
        }
        size++;
        arr[size - 1] = elem;
        int i = size - 1;
        while (i > 0 && arr[i] < arr[(i - 1) / 2])
        {
            swap(arr[i], arr[(i - 1) / 2]);
            i = (i - 1) / 2;
        }
    }

    T getMin() // 返回最小值
    {
        return arr[0];
    }

    T extractMin() // 提取最小值
    {
        if (isEmpty())
        {
            return -1;
        }
        T root = arr[0];
        arr[0] = arr[size - 1];
        size--;
        int i = 0;
        while (2 * i + 1 < size)
        {
            int leftChild = 2 * i + 1;
            int rightChild = 2 * i + 2;
            if (rightChild < size && arr[leftChild] > arr[rightChild])
            {
                leftChild = rightChild;
            }
            if (arr[i] <= arr[leftChild])
            {
                break;
            }
            swap(arr[i], arr[leftChild]);
            i = leftChild;
        }
        return root;
    }

    bool find(T elem)  //查找
    {
        for (int i = 0; i < size; i++)
        {
            if (arr[i] == elem)
            {
                return true;
            }
        }
        return false;
    }

    void deleteElem(T elem)  //删除队列元素
    {
        if (isEmpty() || !find(elem))
        {
            return;
        }
        int i;
        for (i = 0; i < size; i++)
        {
            if (arr[i] == elem)
            {
                break;
            }
        }
        arr[i] = arr[size - 1];
        size--;
        while (i < size && arr[i] < arr[(i - 1) / 2])
        {
            swap(arr[i], arr[(i - 1) / 2]);
            i = (i - 1) / 2;
        }
        while (2 * i + 1 < size)
        {
            int leftChild = 2 * i + 1;
            int rightChild = 2 * i + 2;
            if (rightChild < size && arr[leftChild] > arr[rightChild])
            {
                leftChild = rightChild;
            }
            if (arr[i] <= arr[leftChild])
            {
                break;
            }
            swap(arr[i], arr[leftChild]);
            i = leftChild;
        }
    }
};

int main()
{
    PriorityQueue<int> pq(5);
    pq.insert(3);
    pq.insert(1);
    pq.insert(4);
    cout << pq.getMin() << endl;
    cout << pq.extractMin() << endl;
    cout << pq.getSize() << endl;
    pq.deleteElem(4);
    cout << pq.find(4) << endl;
    return 0;
}

运行结果截图:

最小堆和最大堆只有比较函数不同。最小堆使用 < 比较,最大堆使用 > 比较。所以要将最小堆修改为最大堆,只需要修改比较函数即可。这里对应的修改代码为:

T getMax() // 返回最大值 
{ 
  return arr[0]; 
}

T extractMax() // 提取最大值
{ 
  if (isEmpty()) 
  { 
    return -1; 
  } 
  T root = arr[0]; 
  arr[0] = arr[size - 1]; 
  size--; 
  int i = 0; 
  while (2 * i + 1 < size) 
  { 
    int leftChild = 2 * i + 1; 
    int rightChild = 2 * i + 2; 
    if (rightChild < size && arr[leftChild] < arr[rightChild]) 
    { 
      leftChild = rightChild; 
    }
    if (arr[i] >= arr[leftChild]) 
    { 
      break; 
    } 
    swap(arr[i], arr[leftChild]); 
    i = leftChild; 
  } 
  return root; 
}

可以看到,这里把 < 改为 > ,将 getMin() 改为 getMax(),将 extractMin() 改为 extractMax()。这样,堆中最大的值会在堆顶,所以这就是一个最大堆了。

总结

优先队列是一种抽象数据结构,定义了插入、删除和获取最大/最小元素等操作。堆是一种具体的数据结构,可以用来实现优先队列。堆是一个近似完全二叉树,并且满足堆序性质:父节点的值总是大于(或小于)子节点的值。

二叉堆是一种特殊的堆,完全二叉树,通常用数组表示。二叉堆很适合实现优先队列,时间复杂度为O(logn) 。优先队列强调数据元素的优先级与排序,堆提供了一种数据结构来高效实现这一功能。

参考文献

[1]张铭,王腾蛟,赵海燕编著,《数据结构与算法》,高等教育出版社,2008.6

[2] (美) 乔兹德克(Drozdek, A.) 著 徐丹,吴伟敏 译  C++数据结构与算法(第4版)(国外计算机科学经典教材)清华大学出版社2014-10-01

[3] (美)萨尼 著,王立柱,刘志红 译,数据结构、算法与应用 C++语言描述(原书第2版)机械工业出版社,2015-04-01

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

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

相关文章

在Jupyter notebook中添加虚拟环境

通常我们打开Jupyter notebook&#xff0c;创建一个新文件&#xff0c;只有一个Python3&#xff0c;但是我们也会想使用自己创建的虚拟环境&#xff0c;很简单仅需几部即可将自己的conda环境添加到jupyter notebook中。 1. 创建并激活conda环境&#xff08;已有可跳过&#xf…

【QT进阶】Qt http编程之实现websocket server服务器端

往期回顾 【QT进阶】Qt http编程之json解析的简单介绍-CSDN博客 【QT进阶】Qt http编程之nlohmann json库使用的简单介绍-CSDN博客 【QT进阶】Qt http编程之websocket的简单介绍-CSDN博客 【QT进阶】Qt http编程之实现websocket server服务器端 一、最终效果 通过ip地址和端口…

Redis入门到通关之Redis数据结构-Hash篇

文章目录 ☃️ 概述☃️底层实现☃️源码☃️其他 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后…

使用 vllm 本地部署 cohere 的 command-r

使用 vllm 本地部署 cohere 的 command-r 0. 引言1. 安装 vllm2. 本地部署 cohere 的 command-r3. 使用 cohere 的 command-r 0. 引言 此文章主要介绍使用 使用 vllm 本地部署 cohere 的 command-r。 1. 安装 vllm 创建虚拟环境&#xff0c; conda create -n myvllm python…

微软开源了Phi-3-mini适用于移动硬件设备

&#x1f989; AI新闻 &#x1f680; 微软开源了Phi-3-mini适用于移动硬件设备 摘要&#xff1a;微软最新开源的小参数大语言模型Phi-3-mini&#xff0c;包括其架构特点、训练数据、性能测试以及未来发布计划。该模型拥有38亿参数&#xff0c;占用内存少&#xff0c;且在语言…

JVM--Java对象到底存在哪?

Java对象存放在堆中&#xff0c;但堆又分为新生代和老年代&#xff0c;新生代又细分为 Eden、From Survivor、To Survivor。那我们创建的对象到底在哪里&#xff1f; 堆分为新生代和老年代&#xff0c;新生代用于存放使用后就要被回收的对象&#xff08;朝生夕死&#xff09;&a…

单片机学习过程

继电器光耦隔离电压转换步进电机直流电机 arduino是目前最好用的一种&#xff0c;他提供了完整的设备库文件&#xff0c;任何外部设备只要查找相应的库&#xff0c;就可以很方便的使用 &#xff0c; 但是如果不去学习51 或stm32 或 嵌入式玩玩还可以&#xff0c;如果碰到没有实…

Navicat和MySQL的安装、破解以及MySQL的使用(详细)

1、下载 Navicat Navicat 官网&#xff1a;www.navicat.com.cn/ 在产品中可以看到很多的产品&#xff0c;点击免费试用 Navicat Premium 即可&#xff0c;是一套多连数据库开发工具&#xff0c;其他的只能连接单一类型数据库 点击试用 选择系统直接下载 二、安装 Navicat 安…

【C++】---STL之vector的模拟实现

【C】---STL之vector的模拟实现 一、vector在源码中的结构&#xff1a;二、vector类的实现&#xff1a;1、vector的构造2、析构3、拷贝构造4、赋值运算符重载5、迭代器6、operator[ ]7、size()8、capacity()9、reserve()10、resize()11、empty()12、push_back()13、pop_back()1…

Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结

Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结 在深度学习中&#xff0c;优化器的目标是通过调整模型的参数&#xff0c;最小化&#xff08;或最大化&#xff09;一个损失函数。 优化器使用梯度下降等迭代方法来更新模型的参数&#xff0c;以使损失函数…

【JavaScriptthreejs】对于二维平面内的路径进行扩张或缩放

目标 对指定路径 [{x,y,z},{x,y,z},{x,y,z},{x,y,z}.........]沿着边缘向内或向外扩张&#xff0c;达到放大或缩小一定范围的效果&#xff0c;这里我们获取每个点&#xff08;这里是Vector3(x,y,z)&#xff09;,获取前后两个点和当前点的坐标&#xff0c;计算前后两点的向量&a…

AJAX——案例

1.商品分类 需求&#xff1a;尽可能同时展示所有商品分类到页面上 步骤&#xff1a; 获取所有的一级分类数据遍历id&#xff0c;创建获取二级分类请求合并所有二级分类Promise对象等待同时成功后&#xff0c;渲染页面 index.html代码 <!DOCTYPE html> <html lang&qu…

【数据库】MongoDB

文章目录 [toc]数据库操作查询数据库切换数据库查询当前数据库删除数据库查询数据库版本 数据集合操作创建数据集合查询数据集合删除数据集合 数据插入插入id重复的数据 数据更新数据更新一条丢失其他字段保留其他字段 数据批量更新 数据删除数据删除一条数据批量删除 数据查询…

S-Edge网关:柔性部署,让物联网接入更统一

S-Edge网关是什么&#xff1f; 网关是在实际物理世界与虚拟网络世界相连接的交叉点&#xff0c;为了让这个交叉点尽可能的复用&#xff0c;无需每种设备都配套一种连接方式&#xff0c;边缘网关主要就是用于传感器等物理设备与网络实现数据交互的通用设备&#xff0c;也称为物…

跨部门协作中的沟通困境与平台建设策略——以软硬件研发为例

一、背景 在科技行业&#xff0c;跨部门合作的重要性不言而喻&#xff0c;然而实际工作中&#xff0c;经常会遭遇沟通不畅的现象。以软件与硬件研发部门为例&#xff0c;两者在产品研发过程中经常需要紧密协作&#xff0c;但却时常出现信息传递障碍。当你试图阐述观点时&#…

SpringCloud系列(11)--将微服务注册进Eureka集群

前言&#xff1a;在上一章节中我们介绍并成功搭建了Eureka集群&#xff0c;本章节则介绍如何把微服务注册进Eureka集群&#xff0c;使服务达到高可用的目的 Eureka架构原理图 1、分别修改consumer-order80模块和provider-payment8001模块的application.yml文件&#xff0c;使这…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

Linux(韦东山)

linux和windows的差别 推荐学习路线 先学习 应用程序 然后&#xff1a; 驱动程序基础 最后&#xff1a;项目 韦东山课程学习顺序 看完第六篇之后&#xff0c;还可以继续做更多的官网的项目 入门之后&#xff0c;根据自己的需要学习bootloader / 驱动大全 / LVGL

微信小程序实时日志使用,setFilterMsg用法

实时日志 背景 为帮助小程序开发者快捷地排查小程序漏洞、定位问题&#xff0c;我们推出了实时日志功能。开发者可通过提供的接口打印日志&#xff0c;日志汇聚并实时上报到小程序后台。开发者可从We分析“性能质量->实时日志->小程序日志”进入小程序端日志查询页面&am…

数据结构(学习笔记)王道

一、绪论 1.1 数据结构的基本概念 数据&#xff1a;是信息的载体&#xff0c;是描述客观事物属性的数、字符以及所有输入到计算机中并被计算机程序识别和处理的符号的集合。&#xff08;计算机程序加工的原料&#xff09;数据元素&#xff1a;数据的基本单位&#xff0c;由若干…