C++中優先隊列和sort自定義排序算法對比!!
C++優先隊列
C++中優先隊列常用作大頂堆和小頂堆,定義格式如下:
定義
priority_queue<Type, Container, Functional>;
//Type是數據類型,Container爲保存數據的容器,Functional爲元素比較方式
//以int爲例定義大頂堆的兩種形式,默認是大頂堆,元素從大到小排序
priority_queue<int, vector<int>, less<int>> q1;
priority_queue<int> q2;
//以int爲例定義小頂堆,元素從小到大排序
priority_queue<int, vector<int>, greater<int>> q3;
自定義數據結構
注:當數據類型爲用戶自定義類或結構體時,必須定義相應的排序規則!!優先隊列中有兩種方式定義排序規則
- 重載operater<或operator>
- 創建大頂堆時重載operator<,對應less方法,元素降序
- 創建小頂堆時重載operator>,對應greater方法,元素升序
- 重寫仿函數cmp
- 聲明比較類cmp
struct Node{
int x;
int y;
Node(int a, int b):x(a), y(b){}
};
//1.重載operator<爲自定義結構體創建大頂堆(降序)
bool operator<(Node a, Node b){
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
//重載了operator<,所以可以對Node創建大頂堆
priority_queue<Node, vector<Node>, less<Node>> q1;
//2.聲明比較類cmp
struct cmp{
bool operator()(Node a, Node b){
//a < b時爲降序,a > b時爲升序,此時爲降序
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
};
//此時爲大頂堆,元素降序,注意cmp使用的方式,不帶"()"
priority_queue<Node, vector<Node>, cmp> q2;
C++ sort函數
C++sort()默認按照升序排列,若實現自定義排序,則常用三種方法:
- 自定義比較函數cmp
- 重載比較運算符’<’
- 聲明比較類
struct Node{
int x;
int y;
Node(int a, int b):x(a), y(b){}
};
//1.自定義比較函數
bool cmp(Node a, Node b){
//在sort函數中,a < b爲升序,a > b爲降序,此時爲升序(和優先隊列中<的含義相反)
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
vector<Node> v1;
...
sort(v1.begin(), v1.end(), cmp());//此時爲升序,注意cmp調用方式後帶"()"
//2.重載比較運算符“<"
bool operator<(Node a, Node b){
//a < b爲升序,a > b爲降序,此時爲升序
//若想改爲降序,可將下方的代碼改爲 '>'
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
//此時爲升序
sort(v1.begin(), v1.end());
//3.聲明比較類
struct cmp{
bool operator()(Node a, Node b){
//sort自定義排序函數中a < b表示升序,a > b爲降序
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
};
//此時爲升序,注意cmp的調用方式,後帶"()"
sort(v1.begin(), v1.end(), cmp());
兩個自定義函數對比
- priority_queue有兩種自定義方式:重載操作符和聲明比較類;sort相比於前者增加一個定義比較函數;
- 默認排序方式不同:priority_queue默認爲大頂堆,降序;sort默認升序
- 自定義運算方式不同:比如"a < b"在priority_queue中代表降序,而在sort中代表升序
- 調用方式不同:定義比較類時,priority_queue調用過程中不需要"()"–>cmp,而sort無論調用自定義比較函數還是比較類都需要加上"()"–>cmp()
總結
兩者之間定義運算方式是完全相反的,爲了方便記憶,經常給自己洗腦,僅供大家參考,如果錯誤請指出,感謝
priority_queue中:“a < b” 對應less方法,less爲大頂堆,大頂堆就是降序;“a > b” 對應greater方法,greater爲小頂堆,小頂堆爲降序;
sort中:"a < b"代表前一個元素小於後一個元素,爲升序;"a > b"代表前一個元素大於後一個元素,爲降序;
舉個栗子
struct Node{
int x, y;
Node(int a=0, int b=0):
x(a),y(b){}
};
struct cmp{
bool operator()(Node a, Node b){
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
};
int main(){
priority_queue<Node, vector<Node>, cmp> q1;
for(int i = 5; i >= 0; i--)
q1.push(Node(rand(), rand()));
cout<<"-------priority_queue--------"<<endl;
while(!q1.empty()){
cout<<q1.top().x<<" "<<q1.top().y<<endl;
q1.pop();
}
vector<Node> s;
for(int i = 0; i <= 5; i++){
s.push_back(Node(rand(), rand()));
}
sort(s.begin(), s.end(), cmp());
cout<<"-------sort--------"<<endl;
for(auto a : s){
cout<<a.x<<" "<<a.y<<endl;
}
return 0;
}
//輸出結果:priority_queue中降序,sort爲升序
-------priority_queue--------
29358 11478
28145 5705
26500 6334
24464 26962
18467 41
15724 19169
-------sort--------
153 3902
491 9961
5436 4827
11942 2995
14604 32391
16827 23281
參考鏈接:
1.https://blog.csdn.net/weixin_41588502/article/details/86620305
2.https://www.cnblogs.com/Deribs4/p/5657746.html