跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

C++ 优先队列(Priority Queue)核心原理与实战应用

优先队列是一种元素按优先级排序的数据结构,STL 中通过 priority_queue 实现,底层依赖二叉堆。文章讲解了其默认最大堆行为及自定义比较器构建最小堆的方法,剖析了插入与删除操作的上溯下溯机制。结合任务调度、Dijkstra 最短路径及哈夫曼编码等场景,展示了优先队列在提升系统效率与算法优化中的实际应用价值。

CloudNative发布于 2026/3/30更新于 2026/4/252 浏览
C++ 优先队列(Priority Queue)核心原理与实战应用

C++ 优先队列(Priority Queue)详解

在 C++ 编程中,数据结构是处理数据的核心工具。在众多结构中,**优先队列(Priority Queue)**因其独特的排序机制而占据重要地位。与普通队列不同,它不遵循先进先出(FIFO)原则,而是根据元素的优先级进行调度。

一、优先队列的概念

想象一个特殊的队伍,成员不是按到达顺序排队,而是根据'重要性'标签排列。例如医院急诊室,重伤患者会优先得到救治。优先队列正是如此:优先级最高的元素始终位于队首,随时准备被处理。

二、C++ 中的使用方式

1. 默认行为:最大堆

C++ STL 提供的 priority_queue 类默认实现的是大顶堆。包含 <queue> 头文件后,最大的元素会自动排在队首。

#include <iostream>
#include <queue>

int main() {
    std::priority_queue<int> pq;
    pq.push(5);
    pq.push(10);
    pq.push(3);
    
    std::cout << "队首元素(最大值): " << pq.top() << std::endl;
    pq.pop();
    std::cout << "队首元素(最大值): " << pq.top() << std::endl;
    return 0;
}

每次 push 都会自动调整堆结构,top 获取当前最大值,pop 移除队首元素。

2. 自定义规则:最小堆

若需小顶堆(最小值在队首),可定义比较函数或函数对象。

#include <iostream>
#include <queue>
#include <vector>

struct Compare {
    bool operator()(int a, int b) {
        return a > b; // 返回 true 表示 a 的优先级低于 b
    }
};

int main() {
    std::priority_queue<int, std::vector<int>, Compare> pq;
    pq.push(5);
    pq.push(10);
    pq.push(3);
    
    std::cout << "队首元素(最小值): " << pq.top() << std::endl;
    return 0;
}

通过重载 operator(),我们可以灵活控制元素的排序逻辑。

三、底层原理:二叉堆

priority_queue 的底层通常由**二叉堆(Binary Heap)**实现。这是一种完全二叉树结构,分为大顶堆和小顶堆。

  • 大顶堆:父节点值大于等于子节点值。
  • 小顶堆:父节点值小于等于子节点值。

1. 插入操作(Push)

新元素加入时,先放在末尾,然后向上调整(Sift Up),直到满足堆性质。

template<typename T>
void siftUp(std::vector<T>& heap, int idx) {
    while (idx > 0) {
        int parent = (idx - 1) / 2;
        if (heap[parent] < heap[idx]) { // 大顶堆示例
            std::swap(heap[parent], heap[idx]);
            idx = parent;
        } else {
            break;
        }
    }
}

2. 删除操作(Pop)

删除队首元素时,将最后一个元素移至队首,然后向下调整(Sift Down)。

template<typename T>
void siftDown(std::vector<T>& heap, int idx, int size) {
    int largest = idx;
    int left = 2 * idx + 1;
    int right = 2 * idx + 2;

    if (left < size && heap[left] > heap[largest])
        largest = left;
    if (right < size && heap[right] > heap[largest])
        largest = right;

    if (largest != idx) {
        std::swap(heap[idx], heap[largest]);
        siftDown(heap, largest, size);
    }
}

四、典型应用场景

1. 任务调度

操作系统或任务管理系统常利用优先队列管理任务。高优先级任务(如紧急工单)会被优先处理。

#include <iostream>
#include <queue>
#include <string>
#include <vector>

struct Task {
    std::string name;
    int priority;
    Task(const std::string& n, int p) : name(n), priority(p) {}
};

struct TaskCompare {
    bool operator()(const Task& t1, const Task& t2) {
        return t1.priority < t2.priority; // 优先级高的在前
    }
};

int main() {
    std::priority_queue<Task, std::vector<Task>, TaskCompare> taskQueue;
    taskQueue.push(Task("任务 1", 5));
    taskQueue.push(Task("任务 2", 3));
    taskQueue.push(Task("任务 3", 8));

    while (!taskQueue.empty()) {
        Task currentTask = taskQueue.top();
        std::cout << "正在处理任务:" << currentTask.name 
                  << ",优先级:" << currentTask.priority << std::endl;
        taskQueue.pop();
    }
    return 0;
}

2. 图算法:Dijkstra 最短路径

在寻找单源最短路径时,优先队列能高效选出当前距离起点最近的未访问节点。

#include <iostream>
#include <queue>
#include <vector>
#include <climits>

struct Node {
    int id;
    int distance;
    std::vector<Node*> neighbors;
    Node(int i) : id(i), distance(INT_MAX) {}
};

struct NodeCompare {
    bool operator()(const Node* n1, const Node* n2) {
        return n1->distance > n2->distance; // 距离小的优先
    }
};

void dijkstra(Node* source) {
    std::priority_queue<Node*, std::vector<Node*>, NodeCompare> pq;
    source->distance = 0;
    pq.push(source);

    while (!pq.empty()) {
        Node* currentNode = pq.top();
        pq.pop();

        for (Node* neighbor : currentNode->neighbors) {
            int newDist = currentNode->distance + 1;
            if (newDist < neighbor->distance) {
                neighbor->distance = newDist;
                pq.push(neighbor);
            }
        }
    }
}

3. 数据压缩:哈夫曼编码

构建哈夫曼树时,优先队列用于反复选取频率最低的两个节点合并,从而生成最优前缀码。

#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>

struct HuffmanNode {
    char data;
    int frequency;
    HuffmanNode* left;
    HuffmanNode* right;
    HuffmanNode(char d, int f) : data(d), frequency(f), left(nullptr), right(nullptr) {}
};

struct HuffmanNodeCompare {
    bool operator()(const HuffmanNode* n1, const HuffmanNode* n2) {
        return n1->frequency > n2->frequency; // 频率低的优先
    }
};

HuffmanNode* buildHuffmanTree(const std::unordered_map<char, int>& freqMap) {
    std::priority_queue<HuffmanNode*, std::vector<HuffmanNode*>, HuffmanNodeCompare> pq;

    for (const auto& pair : freqMap) {
        pq.push(new HuffmanNode(pair.first, pair.second));
    }

    while (pq.size() > 1) {
        HuffmanNode* leftNode = pq.top(); pq.pop();
        HuffmanNode* rightNode = pq.top(); pq.pop();
        HuffmanNode* parentNode = new HuffmanNode('\0', leftNode->frequency + rightNode->frequency);
        parentNode->left = leftNode;
        parentNode->right = rightNode;
        pq.push(parentNode);
    }
    return pq.top();
}

通过上述示例可以看出,优先队列在需要动态维护有序性的场景中具有不可替代的作用。掌握其原理与用法,能让代码在处理复杂逻辑时更加高效。

目录

  1. C++ 优先队列(Priority Queue)详解
  2. 一、优先队列的概念
  3. 二、C++ 中的使用方式
  4. 1. 默认行为:最大堆
  5. 2. 自定义规则:最小堆
  6. 三、底层原理:二叉堆
  7. 1. 插入操作(Push)
  8. 2. 删除操作(Pop)
  9. 四、典型应用场景
  10. 1. 任务调度
  11. 2. 图算法:Dijkstra 最短路径
  12. 3. 数据压缩:哈夫曼编码
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • 双指针算法实战:快乐数与盛最多水的容器
  • 利用程序员技能进行语音识别和自然语言处理
  • PyWebIO 低代码开发指南:5 个实战案例构建 Python Web 应用
  • 基于 Xilinx FPGA 的 RISC-V 五级流水线 CPU 设计实战
  • Pi0 机器人控制中心:实现智能操控
  • Web 前端开发全维准备指南
  • ToDesk ToClaw:AI Agent 如何真正融入日常工作流
  • OpenClaw Zero Token 基于浏览器自动化实现大模型免 Token 调用
  • 数据结构:单链表详解
  • 基于FPGA与MATLAB的超声多普勒频移解调应用
  • 从人类视频到机器人跳舞:BeyondMimic 全流程解析与 rl_sar 部署实践
  • 基于 YOLOv8 系列的乡村道路路面缺陷智能检测与预警系统开发
  • 腿式机器人 IMU 融合与状态估计实战(二)
  • DeepSeek 提示词降低论文 AI 检测率方案
  • Windows 环境下 OpenClaw 环境搭建与部署指南
  • Python 爬虫数据存储实战:NoSQL 数据库核心应用
  • Windows 7 安装 Python 3.9+ 配置指南
  • 数字图像处理与FPGA实现:算法与硬件思维的桥梁
  • 基于 llama.cpp 的本地大模型部署教程
  • 基于原生 JavaScript 的 Web 实用工具:成绩统计、完数查找与数组去重

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online