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

你可能感兴趣的:(LeetCode)