STL 之 priority_queue 的介紹與簡單示例
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; }