欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > priority_queue底层实现细节

priority_queue底层实现细节

2025/1/23 10:23:08 来源:https://blog.csdn.net/qhy850716/article/details/145308302  浏览:    关键词:priority_queue底层实现细节

一、priority_queue介绍

优先级队列只提供了 push() pop() top() 函数,本质是一个堆,所以只有堆顶的元素有意义。

本质也是容器适配器,用的是 vector,就像数据结构阶段实现的堆一样,但是由于模板的引入,在这里的优先级队列支持传入比较函数对象来实现不同情况的比较,从而使堆顶的 top 是符合要求的。

priority_queue 与 sort 的对比

两者都是通过传入比较函数对象来实现特定的比较,但是底层是不同的。

(1)priority_queue 是通过模板参数来接受收比较函数对象的,sort 函数是通过函数参数来接受比较函数对象的。

(2)所以一个是类模板传类型,一个是函数模板传对象。

二、部分代码展示

#pragma once
#include<vector>
using namespace std;
namespace bit
{template<class T>struct Less{bool operator(const T& x1, const T& x2){return x1 < x2;}};template<class T>struct Greater{bool operator(const T& x1, const T& x2){return x1 > x2;}};// 默认传递大堆,类模板传类型,函数模板传对象(要有())template<class T, class Container = vector<T>, class Cmp = Less<T>>class priority_queue{public:void adjustup(size_t child){Cmp cmp;// 0 1 2int parent = (child - 1) / 2;while (child > 0) {if (cmp(_con[parent], _con[child])){std::swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}void adjustdown(size_t parent){Cmp cmp;int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && cmp(_con[child], _con[child + 1]))child++;if (cmp(_con[parent], _con[child])){std::swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}elsebreak;}}void push(const T& x){_con.push_back();adjustup(_con.size() - 1);}void pop(){std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjustdown(0);}bool empty(){return _con.size() == 0;}const T& top(){return _con[0];}size_t size(){return _con.size();}private:Container _con;};
}

三、细节

push 和 pop 其实就是在维护一个堆,真正实现功能的是向上向下调整函数。

我们这里也和库一样实现两个比较类 Less 和 Greater,分别对应的是大堆和小堆。

要实现向上向下调整函数就一定要知道如何比较父子节点,此时比较类就可以通过模板参数来影响比较,实现功能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com