priority_queue 接口使用(仿函数、函数指针解决优先级队列存放自定义类型元素、指针类型元素)
创始人
2024-05-11 17:25:19
0

一、priority_queue  优先队列本质就是 堆

堆: 完全二叉树,任意结点比其孩子结点小->小根堆, 任意结点比其孩子结点大->大根堆,

头文件包含:#include 

二、优先级队列的模板参数列表:

template ,  class Compare = less > class priority_queue;

第二个参数指的是采用什么底层容器进行存储,默认使用vector,因为优先级队列的底层结构就是堆,而堆是一种完全二叉树,完全二叉树就适应这种顺序存储的结构

第三个参数给出的是什么样的比较方式默认采用less方式进行比较从而生成大堆,如果想要使其生成小堆,在模板参数中给出greater。        如果要使用greater 则需要包含头文件#include

三、基本接口的使用

①构造一个空的优先队列 进行插入

void Testpriority_queue01()
{priority_queue  q;q.push(1);q.push(2);q.push(632);q.push(34);q.push(23);q.push(6);q.push(67);q.push(95);q.push(23);cout << q.size() << endl;cout << q.top() << endl;q.pop();q.pop();q.pop();q.pop();cout << q.size() << endl;cout << q.top() << endl;
}

② 利用迭代器来进行区间构造

    使用greater 第一种做法是错误的,没有考虑到第二个参数。

void Testpriority_queue03()
{// priority_queue > q; 错误priority_queue , greater> q;q.push(1);q.push(2);q.push(632);q.push(34);q.push(23);q.push(6);q.push(67);q.push(95);q.push(23);cout << q.size() << endl;cout << q.top() << endl;q.pop();q.pop();q.pop();q.pop();cout << q.size() << endl;cout << q.top() << endl;
}

④ 关于自定义类型数据的插入

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};void Testpriority_queue04()
{priority_queue q;Date d1(2023, 1, 12);Date d2(2023, 1, 13);Date d3(2023, 1, 11);q.push(d1);q.push(d2);q.push(d3);cout << q.size() << endl;
}

 发生报错,优先队列默认采用less的比较方式来生成一个大堆,可是在这里插入自定义类型Date时,发生了报错,原因显而易见,编译器无法知道数据比较是用Date中的三个参数的哪一个来进行比较。

四、自定义类型数据插入优先级队列发生报错的解决方式

如果编译器无法知道我们的比较方式是如何进行的,那么我们就得告诉编译器如何进行比较

① 【方式一】在Date类中重载比较方式

这种方式易于理解,你不知道怎么比,那我就在Date类中告诉你怎么比较,该用谁来与谁来进行比较。

    bool operator<(const Date& d)const{return _day < d._day;}bool operator>(const Date& d)const{return _day > d._day;}

 ② 【方式二】使用函数指针

那么我写一个函数Compare来给编译器传递我进行比较的方式,传参时将Compare放入q之后的()内,即为q(Compare);

但是这样还不够,如果想要使用函数指针作为函数参数,那么必须把函数类型在优先级队列的模板参数列表中给出来。

优先级队列的模板参数列表上面也提到过,第一个参数为存放元素的类型(Date),第二个参数为什么样的容器来存储(vector),第三个参数就需要传入函数指针的类型

如下为函数指针取别名方式:

typedef bool (*PCOM)(const Date& left, const Date& right);  PCOM为该函数指针的别名

如下为定义优先级队列q:

priority_queue, PCOM> q(Compare);

typedef bool (*PCOM)(const Date& left, const Date& right);
bool Compare(const Date& left, const Date& right)
{return left.GetDay() < right.GetDay();
}void Testpriority_queue05()
{priority_queue, PCOM> q(Compare);Date d1(2023, 1, 12);Date d2(2023, 1, 13);Date d3(2023, 1, 11);q.push(d1);q.push(d2);q.push(d3);cout << q.size() << endl;
}

③【方式三】使用仿函数

所谓的仿函数,就是对()进行运算符重载。使之成为一个能表示函数功能的函数。

为什么是Com?  因为优先级队列的第三个参数为一个class类型,所以需要新实现一个类,类中仅需重载()

 如下在Com类中写入一个()运算符重载函数,说明了Date类内的比较方式,接着在优先级队列进行定义的时候将Com作为模板参数传入即可。

class Com
{
public:bool operator()(const Date& left, const Date& right)const{return left.GetDay() < right.GetDay();}
};void Testpriority_queue06()
{priority_queue, Com> q;Date d1(2023, 1, 12);Date d2(2023, 1, 13);Date d3(2023, 1, 11);q.push(d1);q.push(d2);q.push(d3);cout << q.size() << endl;
}

五、对于优先级队列存放指针的探讨

 如上图,优先级队列中存储元素类型模板参数为Date*,即存储的是Date类型的指针,在默认的优先级队列中,比较方式是按照less的方式进行比较,而指针的本质就是一块地址,这个地址本质就是一串整形十六进制数据,这个数据也能依据less的比较方式来在优先级队列中存储,即该队列就是按照地址的高低大小来进行建堆,地址高即数值大就排在靠近堆顶位置。

可是我的本意是用我指针所指向的内容来进行比较,这里却使用了指针的地址来进行比较,显然没有任何意义,那么如何实现我最初的目的呢?

仿函数的使用:

        提供一个ComPtr的指针比较方式的类,类中传入left,right俩个Date类型的指针,利用这俩个指针来调用Date类中的GetDay()函数来告诉编译器所需要比较的内容具体是什么。

class ComPtr
{
public:bool operator()(const Date* left, const Date* right)const{return left->GetDay() < right->GetDay();}
};
void Testpriority_queue07()
{// 优先级队列中存放的是指针priority_queue, ComPtr> q;Date d1(2023, 1, 12);Date d2(2023, 1, 13);Date d3(2023, 1, 11);q.push(&d1);q.push(&d2);q.push(&d3);
}

 按照指针的内容大小来进行建堆:

 

相关内容

热门资讯

春天活动主持词 春天活动主持词  大家上午好!  踏着春天的脚步,踩着春风的节拍,春天已经来到我们中间,春天是生命的...
幼儿园家长会园长致辞 幼儿园家长会园长致辞幼儿园家长会园长致辞亲爱的家长、老师们:首先感谢大家在百忙中抽空参加今天举行的家...
教师节活动主持词 教师节活动主持词  一、什么是主持词  由主持人于节目进行过程中串联节目的串联词。如今的各种演出活动...
百日宴致辞 百日宴致辞范文  在日复一日的学习、工作或生活中,许多人都有过写致辞的经历,对致辞都不陌生吧,在各种...
2021年会总经理简短致辞 2021年会总经理简短致辞范文(通用6篇)  在学习、工作、生活中,许多人都有过写致辞的经历,对致辞...
中学秋季开学典礼主持词 中学秋季开学典礼主持词  中学秋季开学典礼主持词    第一项:升国旗仪式(升旗仪式结束后,请新教师...
婚礼男方家长经典致辞 婚礼男方家长经典致辞  大家好!今天是我儿子××和××小姐结婚的大喜日子,我感到非常高兴和荣幸。高兴...
元宵晚会主持词 关于元宵晚会主持词(通用11篇)  主持词是主持人在台上表演的灵魂之所在。在当今社会生活中,司仪等是...
国学经典诵读比赛主持词 国学经典诵读比赛主持词  主持词可以采用和历史文化有关的表述方法去写作以提升活动的文化内涵。随着社会...
离职感谢词 离职感谢词  在xx近两个月的生活,让我感触很多,首先感谢领导一直以来对我们的包容,感谢x经理的照顾...
年会总经理致辞 年会总经理致辞(精选7篇)  在学习、工作、生活中,大家都经常接触到致辞吧,致辞具有“礼仪性”或“仪...
八十大寿宴会主持词 八十大寿宴会主持词  借鉴诗词和散文诗是主持词的一种写作手法。在当下这个社会中,主持人的需求越来越高...
校园迎新春晚会主持词 校园迎新春晚会主持词  主持词已成为各种演出活动和集会中不可或缺的一部分。在当今不断发展的世界,越来...
同桌的你小品台词参考 同桌的你小品台词参考  王小利和小沈阳上场  王小利:儿子,今天,我带你去见一位特别重要的人物。  ...
文艺汇演主持人串词 文艺汇演主持人串词  开场:  萌:尊敬的各位领导,各位来宾。  泓:亲爱的老师们,同学们。大家  ...
年度总结表彰大会主持词 年度总结表彰大会主持词9篇  总结是指社会团体、企业单位和个人在自身的某一时期、某一项目或某些工作告...
小学庆六一儿童节主持词 小学庆六一儿童节主持词(精选5篇)  契合现场环境的主持词能给集会带来双倍的效果。随着社会一步步向前...
经销商大会主持稿 经销商大会主持稿推荐  经销商大会主持稿(一)  尊敬的各位来宾,各位朋友  大家上午好  (8:5...
年会精彩致辞 年会精彩致辞(通用7篇)  在学习、工作乃至生活中,大家对致辞都不陌生吧,致辞具有很强的实用性和针对...
少儿活动主持人主持词 少儿活动主持人主持词  主持词需要富有情感,充满热情,才能有效地吸引到观众。我们眼下的社会,主持人参...