优先级队列priority_queue的介绍与使用

目录

杂谈

成员函数

构造函数

top

push

pop

empty

swap 

size

emplace

测试代码(使用场景)


杂谈

优先级队列priority_queue的介绍与使用_第1张图片

优先级队列priority_queue是位于头文件中的一个类,它和queue一样,也是一个队列,只不过该队列是按照优先级进行过排列的,priority_queue底层的结构本质就是一个堆,默认是大堆,这一点和下图的模板参数Compare有关。

优先级队列priority_queue也是一个容器适配器,如下图中第二个模板参数就表示priority_queue应该适配什么容器完成priority_queue的功能,可以看到下图中STL标准库默认选择vector作为优先级队列的默认适配容器,为什么不是deque呢?因为优先级队列底层就是一个堆,在插入或删除数据时需要AdjustUp或者AdjustDown调整数据,这需要大量使用operator[],deque虽然也支持operator[],但在<>一文中也说过相比于vector的operator[]底层直接挪动指针,deque的operator[]计算比较复杂,大量使用时会降低性能,因此vector更适合做优先级队列的默认适配容器。第三个模板参数表示一种可调用对象的类型,比如可以是函数的类型,仿函数的类型,函数指针的类型。他是干嘛的呢?是用于给优先级队列确定元素优先级的一套比较规则。规则可以规定:值较大的元素优先级高。规则也可以规定:值较小的元素优先级高。

优先级队列不支持迭代器,如果支持迭代器会导致优先级没法被保证了。

成员函数

构造函数

优先级队列priority_queue的介绍与使用_第2张图片

1.默认构造,都有缺省值,如果显示传参,则需要给形参comp传一个可调用对象,如函数对象(仿函数),函数,函数指针,Compare就表示这些对象的类型;需要给第二个参数cntr传一个容器对象,但注意有一个前提,那就是priority_queue必须适配该容器,如何判断是否适配该容器呢?如下图所示。

优先级队列priority_queue的介绍与使用_第3张图片

2.迭代器区间构造,迭代器类型可以是任意容器的迭代器,如可以通过list的迭代器区间构造优先级队列。

top

优先级队列priority_queue的介绍与使用_第4张图片

取优先级队列中优先级最高的元素,也就是队列中的极大或者极小值,如何判断是极大还是极小呢?看优先级队列的底层实现是建立大堆还是小堆,top函数用于取堆顶的元素,因此如果是大堆,则堆顶的元素是最大值,所以top函数就是用于取优先级队列中的极大值,反之则是极小值。

push

优先级队列priority_queue的介绍与使用_第5张图片

用于将一个元素放进优先级队列中。

pop

用于删除优先级队列中优先级最高,也就是堆顶的元素。

empty

用于判断优先级队列中是否存在有效数据,即是否为空。

swap 

优先级队列priority_queue的介绍与使用_第6张图片

用于交换两个优先级队列对象管理的有效数据。noexcept表示该函数不会抛异常。

size

优先级队列priority_queue的介绍与使用_第7张图片

用于返回优先级队列中有效数据的个数。

emplace

功能和push一样,效率比push高,但会导致代码可读性下降。

测试代码(使用场景)

优先级队列priority_queue的介绍与使用_第8张图片

可以看到值较大的元素优先级较高,即底层的堆顶是极大值,所以STL中的优先级队列底层默认是建大堆的。 

那如何让较小的元素优先级较高,也就是让优先级队列的底层是建立小堆呢?如下图两个红框所示,添加头文件,然后将less类传给优先级队列的第三个模板参数。注意如果想传less给第三个模板参数,则必须先传值给第二个模板参数,如下图传了vector给二个模板参数,否则编译器会认为less是传给第二个模板参数的值,这是一个缺省值的小知识点。

优先级队列priority_queue的介绍与使用_第9张图片

如下图问题也可以通过优先级队列巧妙的解决。

优先级队列priority_queue的介绍与使用_第10张图片

你可能感兴趣的:(STL中容器的介绍与模拟实现,数据结构)