priority_queue 优先队列,其底层是用堆来实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
在优先队列中,没有 front() 函数与 back() 函数,而只能通过 top() 函数来访问队首元素(也可称为堆顶元素),也就是优
先级最高的元素。基本操作有:
empty() 如果队列为空返回真
pop() 删除对顶元素
push() 加入一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列对顶元素
priority_queue 默认为大顶堆,即堆顶元素为堆中最大元素(比如:在默认的int型中先出队的为较大的数)。
基本数据类型(int,double,char等可以直接使用的数据类型),优先队列对他们的优先级设置一般是数字大的优先级高,因
此队首元素就是优先队列内元素最大的那个(如果是 char 型,则是字典序最大的)。
如果我们想要用小顶堆的话需要增加使用两个参数:
priority_queue< int, vector<int>, greater<int> > q; // 小顶堆
priority_queue< int, vector<int>, less<int> > q; // 大顶堆
下面两种优先队列的定义是等价的
priority_queue< int > q;
priority_queue< int,vector<int>,less<int> >;
其中第二个参数( vector ),是来承载底层数据结构堆的容器,第三个参数( less ),则是一个比较类,less 表示数字大的优
先级高,而 greater 表示数字小的优先级高。
如果需要对结构体的优先级设置,有两种方法:
方式一:重载运算符 ‘<’
方式二:把重载的函数写在结构体外
示例代码:
// priority_queue_test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <queue>
#include <iostream>
#include <functional>
#include <string>
using std::vector;
using std::priority_queue;
//方式一(比较函数写在结构体外面):
struct student{
std::string name;
int score;
student(std::string _name = "", int _score = 0):name(_name), score(_score) {}
};
struct cmp{
bool operator() (const student& a, const student& b ){
return a.score > b.score;
}
};
//方式二(重载操作符):
struct Fruit{
std::string name;
double price;
Fruit(std::string _name = "", double _price = 0):name(_name), price(_price) {}
friend bool operator < (const Fruit left, const Fruit right ){
return left.price > right.price;
}
};
//输入n个整数,找出其中最小的k个数。例如输入8、1、7、2、6、3、5、4这8个数字,则最小的4个数字是1,2,3,4。
vector<int> GetLeastNumbers(vector<int> rawArray, int k)
{
int size = rawArray.size();
vector<int> ret;
if (size == 0 || k <= 0 || k > size)
return ret;
priority_queue<int> _queue;
for (int i = 0; i < size; i++) {
if (_queue.size() < k)
_queue.push(rawArray[i]);
else {
if (rawArray[i] < _queue.top()) {
_queue.pop();
_queue.push(rawArray[i]);
}
}
}
while (!_queue.empty()) {
ret.push_back(_queue.top());
_queue.pop();
}
reverse(ret.begin(), ret.end());
return ret;
}
void test_priority_queue()
{
//默认情况下,数值大的在队首位置(降序)
priority_queue<int> queueLess;
//priority_queue<int, vector<int>, std::less<int>> q;//等同于priority_queue<int> q;
for(int i = 0;i <= 10;i ++)
queueLess.push(i);
while(!queueLess.empty()){
std::cout << queueLess.top() << " ";
queueLess.pop();
}
std::cout << std::endl;
//greater<int>表示数值小的优先级越大
priority_queue<int, vector<int>, std::greater<int> > queueGreater;
for(int i = 0;i <= 10;i ++)
queueGreater.push(i);
while(!queueGreater.empty()){
std::cout << queueGreater.top() << " ";
queueGreater.pop();
}
std::cout << std::endl;
}
void test_priority_queue2()
{
//
priority_queue<student, vector<student>, cmp> nodeQueue;
student node1, node2, node3;
node1.name = "tom";
node1.score = 60;
node2.name = "kelly";
node2.score = 80;
node3.name = "mary";
node3.score = 70;
nodeQueue.push(node1);
nodeQueue.push(node2);
nodeQueue.push(node3);
while(!nodeQueue.empty()){
std::cout << nodeQueue.top().name << " : " << nodeQueue.top().score << std::endl;
nodeQueue.pop();
}
}
void test_priority_queue3()
{
//
priority_queue<Fruit> node2Queue;
Fruit _node1, _node2, _node3;
_node2.name = "banana";
_node2.price = 3.2;
_node1.name = "apple";
_node1.price = 4.5;
_node3.name = "grape";
_node3.price = 2.1;
node2Queue.push(_node1);
node2Queue.push(_node2);
node2Queue.push(_node3);
while(!node2Queue.empty()){
std::cout << node2Queue.top().name << " : " << node2Queue.top().price << std::endl;
node2Queue.pop();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
test_priority_queue();
test_priority_queue2();
test_priority_queue3();
//
vector<int> intArray;
intArray.push_back(8);
intArray.push_back(1);
intArray.push_back(7);
intArray.push_back(2);
intArray.push_back(6);
intArray.push_back(3);
intArray.push_back(5);
intArray.push_back(4);
vector<int> rets = GetLeastNumbers(intArray, 4);
for (int i=0; i<rets.size(); ++i){
std::cout << rets[i] << std::endl;
}
system("pause");
return 0;
}