C++优先队列

  重载比较器有两种方式:重载小于号和自定义比较函数(重载括号)。其中,重载小于号可以直接写在你的类里面,需要注意的就是两个const。重载括号需要新开一个类写。
  需要注意的是,优先队列实际的排序顺序和你比较器里面定义的顺序(或者说和其他STL模板相比)是反过来的,例如下面的程序:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

// 方法1:重载小于号
class myPoint1 {
public:
        int x, y;
        myPoint1(int x, int y) : x(x), y(y) { }

        // 方法1:重载小于号,这里的参数const和后面的const都不能少
        // 后面的const修饰的是类函数隐藏的第一个参数 this指针,这表明this指针只读,也即类成员不可修改
        // 注意该用法只能是成员函数,要是类的静态函数或者是非成员函数就不可以在函数名后面加上const
        bool operator < (const myPoint1& p) const
        {
                if (x == p.x) return y < p.y;
                return x < p.x;
        }
};

// 方法2:自定义比较函数
class myPoint2 {
public:
        int x, y;
        myPoint2(int x, int y) : x(x), y(y) { }
};

// 方法2:自定义比较函数
class myComparator {
// 如果是class,public不能少;否则就用struct
public:
        bool operator () (myPoint2 &a, myPoint2 &b)
        {
                if (a.x == b.x) return a.y < b.y;
                return a.x < b.x;
        }
};

std::priority_queue<myPoint1> pq1;

std::priority_queue<myPoint2, std::vector<myPoint2>, myComparator> pq2;

int main()
{
        pq1.push(myPoint1(1, 2));
        pq1.push(myPoint1(2, 1));
        pq1.push(myPoint1(1, 1));
        pq1.push(myPoint1(0, 1));
        pq1.push(myPoint1(2, 2));

        while (!pq1.empty())
        {
                myPoint1 p = pq1.top();
                pq1.pop();
                std::cout << p.x << " " << p.y << std::endl;
        }

        std::cout << "---------------------------" << std::endl;
        
        pq2.push(myPoint2(1, 2));
        pq2.push(myPoint2(2, 1));
        pq2.push(myPoint2(1, 1));
        pq2.push(myPoint2(0, 1));
        pq2.push(myPoint2(2, 2));

        while (!pq2.empty()) {
                myPoint2 p = pq2.top();
                pq2.pop();
                std::cout << p.x << " " << p.y << std::endl;
        }
}

  运行结果是:

2 2
2 1
1 2
1 1
0 1
---------------------------
2 2
2 1
1 2
1 1
0 1

  很显然,这和我们定义的X小在前并不相同,而是相反。具体原因我也不清楚,不过好像是因为优先队列是大根堆,然后top是倒着访问的。

sort自定义比较函数

  下面是一个sort函数自定义比较函数的例子:

#include <iostream>
#include <vector>
#include <algorithm>

std::vector <int> v1 = {3,2,1,5,4,3,6,2,1,4,5,9};

bool cmp(int a, int b)
{
        return a < b;
}

int main()
{
        std::sort(v1.begin(), v1.end(), cmp);

        for (auto &it : v1) {
                std::cout << it << " ";
        }
}

  输出结果是:

1 1 2 2 3 3 4 4 5 5 6 9 

  因为我们的cmp函数的含义是,a是不是应该排在b前面?如果函数返回1,那么a在b前面,而cmp里面写的是 a < b ,所以是从小到大排序。