C++ priority_queue如何自定义比较函数?和sort里面自定义比较函数有何区别?

本文详细解析了C++中priority_queue与sort函数如何使用自定义比较函数,并对比了两者之间的区别。介绍了三种定义比较函数的方法,包括函数对象、全局函数及使用标准库提供的less或greater。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. C++ priority_queue如何自定义比较函数以及和sort里面自定义比较函数的区别

首先看C++ 官方文档对priority_queue的模板定义:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

注意:

  1. 后面两个参数可以不写,因为有默认值,但是如果写了,就必须两个都写,而且要按照顺序填写
  2. Compare是类名!不是对象名
    在algorithm里面一样也有很多函数会用到自定义比较函数,比如sort:
template <class RandomAccessIterator, class Compare>  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

这里需要传入的就不仅仅是类名,而是对象名!
可以注意一下C++里面的其他内部有序的数据结构,如map,set,可以看到,这些Compare都是类名,而不是类的对象!这是非常容易犯的错误。
map:

template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T>>
> class map;

set:

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

总结:最主要的就是sort里面比较函数必须是对象,而priority_queue等则是类名

2. 比较函数有以下几种:

注意:结构体最好在函数后面加上const限定符,否则构造priority_queue等对象的时候可能会报错!
如可能出现以下错误:

Visual Studio编译器错误 C3848 具有类型“type”的表达式会丢失一些 const-volatile
限定符以调用“function”

解决办法就是像下面的第一种里面的代码一样,重载函数调用运算符的时候加上const限定符。

vector<pair<int, int>> vec;

第一种:采用函数对象,关于什么是函数对象可以参考C++ 函数对象(Function Object)是什么?

结构体
struct compare {
	bool operator () (const pair<int, int>& A. const pair<int, int>& B) const {
		return A.second < B.second;
    }
}
sort(vec.begin(), vec.end(), compare{});
sort(vec.begin(), vec.end(), compare());

第二种:采用全局函数,这里应该会进行转换,cmp是一个函数指针,实际用的是一个函数对象
由于这里调用的就是一个实际的函数对象,所以可以直接传入(不用额外构造函数对象)。


函数
bool cmp(const pair<int, int>& A. const pair<int, int>& B) {
	return A.second < B.second;
}
sort(vec.begin(), vec.end(), cmp);
// 不用加()

第三种:采用标准库自带的less或者greater,注意这种也必须传入一个具体的对象,下面两种方法都可以

less或者greater
sort(vec.begin(), vec.end(), less<pair<int, int>>()); 
sort(vec.begin(), vec.end(), less<pair<int, int>>{}); 

在官方文档里面也可以看到,其实less是重载了运算符()的

std::less::operator()
bool operator()( const T& lhs, const T& rhs ) const;

因此我觉得,less<pair<int, int>>{}这种方式是构造一个类的对象,而less<pair<int, int>>()调用的应该是直接调用less<pair<int, int>>重载的()方法,只不过前者也是调用重载的()方法。
可以通过对结构体(即第一种方法进行验证)
验证方法如下:

结构体
struct compare {
	bool operator () (const pair<int, int>& A. const pair<int, int>& B) const {
		cout <<  "()" << endl;
		return A.second < B.second;
    }
}
sort(vec.begin(), vec.end(), compare{});
sort(vec.begin(), vec.end(), compare());

可以发现两种方法都会输出(),说明在比较的过程中都是调用了重载的()函数的。

参考资料:

cppreference

### C++ 中 `priority_queue` 自定义比较器 在 C++ 的标准模板库(STL)中,`std::priority_queue` 是一种容器适配器,默认情况下它是一个最大堆。为了改变其行为并实现最小堆或其他排序逻辑,可以提供一个自定义比较函数。 #### 自定义优先级队列 当创建 `std::priority_queue` 时,可以通过传递第三个参数来指定不同的比较方式: ```cpp #include <queue> #include <functional> struct Compare { bool operator()(const int& lhs, const int& rhs) const { return lhs > rhs; } }; std::priority_queue<int, std::vector<int>, Compare> minHeap; // 或者使用 lambda 表达式作为比较器 auto cmp = [](int a, int b){return a > b;}; std::priority_queue<int, std::vector<int>, decltype(cmp)> customPQ(cmp); ``` 上述代码展示了如通过结构体或 Lambda 函数自定义比较操作[^1]。 #### 排序算法中的重载函数 对于内置类型的数组或向量可以直接调用 `std::sort()` 进行升序排列;如果想要降序或者其他特定顺序,则需传入额外的谓词表达式给该函数: ```cpp #include<algorithm> #include<vector> bool compare(int a, int b){ return a>b; // 实现降序排序 } std::vector<int> vec={7,2,5,3}; std::sort(vec.begin(),vec.end(),compare); // 使用lambda简化写法 std::sort(vec.begin(), vec.end(), [](int a,int b)->bool{return a<b;} ); ``` 此部分说明了如利用外部布尔返回值型的二元运算符来进行定制化排序[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值