C++中優先隊列和sort中自定義排序算法的對比

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());

兩個自定義函數對比

  1. priority_queue有兩種自定義方式:重載操作符和聲明比較類;sort相比於前者增加一個定義比較函數;
  2. 默認排序方式不同:priority_queue默認爲大頂堆,降序;sort默認升序
  3. 自定義運算方式不同:比如"a < b"在priority_queue中代表降序,而在sort中代表升序
  4. 調用方式不同:定義比較類時,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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章