優先級隊列priority_queue自定義比較函數


1.自定義數據類型時

https://blog.csdn.net/HermitSun/article/details/107101944

 參照378. 有序矩陣中第 K 小的元素

class Point
{
    int val, x, y;
    Point(int val, int x, int y) : val(val), x(x), y(y) {}
    bool operator>(const Point &p) const { return val > p.val; }
};

自定義 定義一個小頂堆,這里的greater運算符函數,參數需要是const,並且需要時const函數,不然會報錯:

this‘ argument has type ‘const xxx‘, but method is not marked const

 初始化時:

priority_queue<Point, vector<Point>, greater<Point>> q;

  q.emplace(1, 1, 1);

greater函數的文檔:

也就是說在堆排序時,調用greater,greater的參數是const的,並且是const成員函數,在內部比較時會用到上面重寫的operator>函數,而const成員函數不能調用非const成員函數,所以會報錯,所以需要將其聲明為const函數,另外如果operator>的參數列表不聲明為const,但operator中為const會導致形參無法賦值。

2.三種方法

https://www.cnblogs.com/Harley-Quinn/p/6104306.html

2.1函數指針

bool greaterInt(const int& lhs, const int& rhs)
{
    return lhs > rhs;
}
priority_queue<int, vector<int>, bool(*)(const int&, const int&)> q(greaterInt);

但這樣寫其實是寫的復雜了,C風格的,不常用。

 2.2函數對象

仿函數類

template <typename T>
struct Greater
{
    bool operator()(const T& lhs, const T& rhs) const
    {
        return lhs > rhs;
    }
};
priority_queue<int, vector<int>, Greater<int>> q;

采用顯式寫法:

priority_queue<int, vector<int>, Greater<int>> q(Greater<int>());

即顯式地調用Greater類的默認構造函數,但這樣會報錯,所以不要這樣。

2.3 lamda表達式

    auto comp = [](const int& lhs, const int& rhs) { return lhs > rhs; };
    priority_queue<int, vector<int>, decltype(comp)> q(comp);

官方文檔中給出的具體的例子,https://en.cppreference.com/w/cpp/container/priority_queue/priority_queue:

#include <iostream>
#include <queue>
#include <vector>
#include <utility>
 
using my_pair_t = std::pair<size_t,bool>;
 
using my_container_t = std::vector<my_pair_t>;
 
int main()
{
    auto my_comp =
        [](const my_pair_t& e1, const my_pair_t& e2) 
        { return e1.first > e2.first; };
    std::priority_queue<my_pair_t,
                        my_container_t,
                        decltype(my_comp)> queue(my_comp);
    queue.push(std::make_pair(5, true));
    ....
}

但是結合第一節中的討論,如果存儲的類型是指針類型,那么參數就不能是const的,有兩個具體的舉例:

23. 合並K個升序鏈表

        auto cmp=[](const ListNode* & a,const ListNode* & b){return a->val>b->val;};//不能用const,是錯的!OMG
        priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> pq(cmp);

注意,定義的cmp參數類型是指針類型,並且是const的,提交會報錯:

 本人手動嘗試了基本類型的指針:

    auto comp = [](const int*& lhs, const int*& rhs) { return *lhs > *rhs; };
    priority_queue<int*, vector<int*>, decltype(comp)> q(comp);
    int* a=new int(5);
    int *b=new int(6);
    q.push(a);
    q.push(b);

會報錯:

error: cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'

搜索相關的結果都是  臨時變量不能用作非const引用。所以這個錯誤的原因未知。

總的修改之后:

        auto cmp=[](ListNode*& a, ListNode*& b){return a->val>b->val;};
        priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> pq(cmp);

 ok.

    auto comp = [](int* & lhs, int* & rhs) { return *lhs > *rhs; };
    priority_queue<int*, vector<int*>, decltype(comp)> q(comp);
    int* a=new int(5);
    int *b=new int(6);
    q.push(a);
    q.push(b);

 ok.

所以如果T是指針類型,那么函數形參中不加const。

3.sort中的cmp函數與優先隊列priority_queue的重載函數重載小於號)的區別

https://blog.csdn.net/weixin_44980441/article/details/107365028

struct fruit
{
    string name;
    int price ;
    friend bool operator < (fruit a,fruit b)
    {
        return a.price>b.price;//低價優先!!!!。
    }
};
bool cmp(fruit a,fruit b){
    return a.price>b.price;//高價優先
}

非常易錯,到現在也分不清。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM