STL 之 priority_queue 的介绍与简单示例

版权声明:本文为博主原创文章,未经博主同意不可随意转载。 https://blog.csdn.net/hellokandy/article/details/81458663

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;
}

猜你喜欢

转载自blog.csdn.net/hellokandy/article/details/81458663