Vue或JS的浮點型乘除法無法精確計算
技術標籤:演算法筆記
優先佇列
priority_queue:優先佇列,底層用堆來進行實現的。在優先佇列中,隊首元素一定是當前佇列中優先順序最高的那一個。
例如,定義好優先順序:
桃子(優先順序3)
梨子(優先順序4)
蘋果(優先順序1)
那麼出隊順序為梨子(4)->桃子(3)->蘋果(1)
可以在任何時候往優先佇列裡面加入(push)元素,而優先佇列底層的資料結構堆(heap)可以隨時呼叫結構,使得每次的隊首元素都是優先順序最大的。
priority_queue的定義
新增標頭檔案#include
priority_queue <typename> name;
priority_queue容器內元素的訪問
只能通過top()函式來訪問隊首元素,也就是優先順序最高的元素。
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
return 0;
}
4
priority_queue常用函式例項解析
(1)push()
push(x)將令x入隊,時間複雜度為O(logN),其中N為當前優先佇列中的元素個數。
(2)top()
top()可以獲得隊首(即堆頂元素),時間複雜度為O(1)。
(3)pop()
pop()令隊首元素出隊,時間複雜度為O(logN),其中N為當前優先佇列中的元素個數。
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
q.pop(); // 令隊首出隊
printf ("%d\n", q.top());
return 0;
}
4
3
(4)empty()
empty()檢測優先佇列是否為空,返回true則空,返回false則非空,時間複雜度O(1)。
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
if(q.empty() == true)
{
printf("Empty\n");
}
else
{
printf("Not Empty\n");
}
q.push(1);
if(q.empty() == true)
{
printf("Empty\n");
}
else
{
printf("Not Empty\n");
}
return 0;
}
Empty
Not Empty
(5)size()
size()返回優先佇列內元素的個數,時間複雜度為O(1)
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.size()); //優先佇列中有三個元素
return 0;
}
3
priority_queue內元素優先順序的設定
(1)基本資料型別的優先順序設定
int,double,char優先順序設定一般是數字大的優先順序越高,(char為字典序最大的)
priority_queue<int> q;
第二種定義方式多兩個引數
vector:填寫的是來承載底層資料結構堆(heap)的容器
less:對第一個引數的比較類,表示的數字越大的優先順序越大
priority_queue<int, vector<int>, less<int>> q;
greater表示數字小的優先順序越大
priority_queue<int, vector<int>, greater<int>> q;
示例:
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int, vector<int>, greater<int>> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
return 0;
}
1
(2)結構體的優先順序設定
通過過載“<”來改變小於號功能,使用友元函式來對其過載。
#include <iostream>
#include <string>
#include <queue>
#include <vector>
using namespace std;
struct fruit
{
string name;
int price;
friend bool operator < (fruit f1, fruit f2)
{
return f1.price > f2.price;
}
}f1, f2, f3;
int main()
{
priority_queue<fruit> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "蘋果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
return 0;
}
蘋果 1
類比sort中的cmp函式,把friend去掉,把小於改成括號,然後把過載的函式寫在結構體外面,同時將其用struct包裝起來。
#include <iostream>
#include <string>
#include <queue>
#include <vector>
using namespace std;
struct fruit
{
string name;
int price;
}f1, f2, f3;
struct cmp
{
bool operator () (fruit f1, fruit f2)
{
return f1.price > f2.price;
}
};
int main()
{
priority_queue<fruit, vector<fruit>, cmp> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "蘋果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
return 0;
}
蘋果 1
如果結構體的資料龐大,建議使用引用來提高效率,此時比較類的引數中需要加上const和&
friend bool operator < (fruit &f1, fruit &f2)
{
return f1.price > f2.price;
}
bool operator () (fruit &f1, fruit &f2)
{
return f1.price > f2.price;
}
priority_queue的常見用途
可以解決一些貪心問題,也可以對Dijkstra演算法進行優化,但使用top()前,必須用empty()判斷優先佇列是否為空,否則可能因為隊空出現錯誤。