优先级队列与仿函数

简介: 优先级队列与仿函数

优先级队列

优先级队列 priority_queue 是一种容器适配器,听起来是队列,其实它的底层数据结构是堆,所谓的优先级为默认越大的数优先级越高,即默认为大堆。

使用方式如下面的代码:

#include<iostream>
#include<queue>
using namespace std;
int main()
{
  priority_queue<int> q;
  priority_queue<int, vector<int>> p;
  priority_queue<int, vector<int>, less<int>> pq;
  priority_queue<int, vector<int>, greater<int>> qp;
  q.push(3);
  q.push(1);
  q.push(4);
  q.push(8);
  q.push(2);
  while (!q.empty())
  {
    cout << q.top() << ' ';
    q.pop();
  }
  cout << endl;
  return 0;
}

其中前三行实例化的对象是等价的,都是建大堆,即 class Container 的默认适配容器是 vector,class Compare 默认的仿函数是 less,只有传了默认适配器后才能传仿函数类或类模板。

仿函数 less(return x < y) 在堆的排序算法中比较部分起的作用是建大堆,greater (return x > y)在堆的排序算法中是建小堆,这与日常认知恰好相反。

优先级队列的底层是堆,那么它的插入和删除的时间复杂度就和堆一样,为 O(logN)

仿函数

仿函数的使用可以使优先级队列的使用者随意控制大小堆,通过参数来传递

所谓仿函数,其实是一个类,但它实例化出的对象可以像函数一样去使用,这个功能在C++中其实是为了替换函数指针的,那么它到底是咋样的?

那么在这,它就起到了比较两个数大小的作用

当然,它也可以配合模板来使用

那么,这么简单的功能,如何在优先级队列中做到改变大小堆的功能呢?

首先,写两个仿函数的类模板,分别用来作堆中 父亲 大于孩子结点 和 父亲 小于孩子结点的比较,在 priority_queue类的模板中添加一个模板参数,用于接收一个类模板

控制传过去的参数为 Less 和 Greater ,用这个模板参数Compare 接收,Compare实例化出的对象即可起到比较两个数大小的作用。若传过来的参数为 Less类模板,即可判断一个数是否小于另一个数;若传过来的参数为 Greater,即可判断一个数是否大于另一个数。

实例化对象 _com

在比较父子结点大小的时候即可使用

所以,当传递模板参数为 Less 的时候,即可控制堆为大堆;当传递模板参数为 Greater 的时候,即可控制堆为小堆。使用下面的代码来测试:

void test1()
{
  zyb::Priority_queue<int, vector<int>, Less<int>> pq;
  pq.push(1);
  pq.push(9);
  pq.push(4);
  pq.push(3);
  while (!pq.empty())
  {
    cout << pq.top() << ' ';
    pq.pop();
  }
  cout << endl;
  zyb::Priority_queue<int, vector<int>, Greater<int>> p;
  p.push(1);
  p.push(9);
  p.push(4);
  p.push(3);
  while (!p.empty())
  {
    cout << p.top() << ' ';
    p.pop();
  }
  cout << endl;
}
int main()
{
  test1();
  return 0;
}

运行结果如下,成功的通过传递的参数不同建立了大堆和小堆

priority_queue 实现源码

命名空间应该自己定义。

#pragma once
#include<vector>
using namespace std;
 
template<class T>
class Greater
{
public:
  bool operator()(const T& x, const T& y)
  {
    return x > y;
  }
};
template<class T>
class Less
{
public:
  bool operator()(const T& x, const T& y)
  {
    return x < y;
  }
};
namespace zyb
{
  template<class T, class Container = vector<T>,class Compare = Less<T>>
  class Priority_queue
  {
  public:
    Priority_queue()
    {}
    Compare _com;
    void adjust_up(int child)
    {
      size_t parent = (child - 1) / 2;
      while (child > 0)
      {        
        if (_com(_con[parent],_con[child]))
        {
          swap(_con[parent], _con[child]);
          child = parent;
          parent = (child - 1) / 2;
        }
        else
        {
          break;
        }
      }
    }
    void adjust_down(int parent)
    {
      int child = parent * 2 + 1;
      while (child < _con.size())
      {
        if (child + 1 < _con.size() && _com(_con[child],_con[parent]))
        {
          child = child + 1;
        }
        if (_com(_con[parent],_con[child]))
        {
          swap(_con[parent], _con[child]);
          parent = child;
          child = 2 * parent + 1;
        }
        else
        {
          break;
        }
      }
    }
    void push(const T& x)
    {
      _con.push_back(x);
      adjust_up(_con.size()-1);
    }
    void pop()
    {
      swap(_con[0], _con[_con.size() - 1]);
      _con.pop_back();
      adjust_down(0);
    }
    size_t size()
    {
      return _con.size();
    }
    T& top()
    {
      return _con[0];
    }
    bool empty()
    {
      return _con.empty();
    }
  private:
    Container _con;
  };
}

从下面官方的定义就可以知道了,为什么传第三个参数的时候,必须先传第二个参数,第二个参数中包含着要比较数据的类型,第三个仿函数模板类型是跟容器里数据类型有关的!

相关文章
|
3天前
|
人工智能 自然语言处理 安全
阿里云AI数智鉴密:AI 生成内容如何拿到一张"防篡改的身份证"
隐形水印 + C2PA签名:让AI生成内容“持证上岗”。
1111 0
|
12天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
3706 4
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
24天前
|
人工智能 缓存 前端开发
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
DeepSeek Harness + DeepSeek V4 Pro 项目实战保姆级教程!手把手带你从零安装开源 AI 编程工具,开发架构图、知识讲解网站、3D 网页游戏、全栈 AI 应用 4 个项目,覆盖运行模式选择、插件安装与开发,看看能不能对标 Claude。
13508 93
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
|
17天前
|
Web App开发 人工智能 API
16 个超火的 DeepSeek Harness 插件,大肥鱼已经落后 N 个版本了。。。
DeepSeek Harness 精选插件推荐合集,从图片识别、浏览器操控、多 Agent 协作到手机远程控制,一口气带你看完 DSH 社区热门的十几个插件,覆盖技能扩展、UI 界面增强、整活玩法三大类,让你的鲸鱼变得更强。
1974 5
|
3天前
|
人工智能 运维 BI
阿里云千问办公QwenWork深度解析:基于Qwen3.8,六大核心能力重构企业全自动化工作流与计费选型指南
传统AI办公工具大多停留在对话问答、文档摘要、简单文案生成层面,只能完成单点碎片化任务,无法自主拆解复杂业务流程,很难串联多工具、多文档、外部业务系统完成端到端完整工作交付。很多企业在落地AI办公的时候,需要组合多款不同工具,来回切换界面,手动复制粘贴中间结果,智能化改造落地门槛居高不下。千问办公QwenWork是整合多款智能体产品能力打造的一体化企业办公智能体平台,底层基座依托Qwen3.8大模型,打通桌面端Agent、云端Agent、企业协同Agent三种运行形态,不再局限简单问答,接收业务目标之后自主拆解任务步骤,调用各类工具,处理文档、表格、浏览器自动化、数据查询,直接输出可交付的办公
1005 0
|
13天前
|
人工智能 Linux iOS开发
Ollama使用教程:Ollama官网下载、Ollama本地部署大模型(2026最新)
Ollama 是一款免费开源的本地大模型运行工具,支持在 Windows/macOS/Linux 上离线运行 Qwen、DeepSeek、Llama 等主流开源模型,数据不出本机、隐私安全。提供 OpenAI 兼容 API,命令行一键拉取/运行/管理模型,无需联网,无调用限制,是开发者与 AI 爱好者部署本地 AI 助手的理想选择。(239 字)
|
9天前
|
人工智能 并行计算 数据可视化
秋叶ComfyUI-AKI最新整合包|完整部署教程+核心指令手册
秋叶ComfyUI-AKI一键整合包,国内适配最优、稳定性最强的商用/学习级版本:全封装虚拟环境、预装90%常用节点、内置绘世启动器与成熟工作流,免配置、零依赖、解压即用,完美兼顾新手入门与专业批量生产需求。(239字)
|
10天前
|
人工智能 监控 测试技术
Qwen3.8-Flash 来了,100万上下文、Agent、Coding 都加强了
8月26日,通义千问发布Qwen3.8-Flash-Next:125B参数、每Token仅激活6B,原生支持26万Token、可扩展至100万上下文;Coding、Agent与工具调用能力显著增强,面向真实软件工程任务,推动大模型从“回答问题”迈向“完成工作”。

热门文章

最新文章