c++自定义排序(总结)

 

以下全是根据使用经验得出的个人总结,供大家参考,如果有什么不对的欢迎指出

 

首先将需要排序的情况分类

需要排序的类型分为   基本类型(int,float...)和自定义类型

需要用到排序的地方   模板函数(sort,merge,for_each...)和模板类

注:模板函数中需要的比较参数是函数名,而模板类中需要的比较参数是类型名(因为是类型所以只能使用函数对象)

 

内置函数对象(关系仿函数)

关系仿函数
tmplate<class T> bool equal_to<T>                   等于
tmplate<class T> bool not_equal_to<T>               不等于
tmplate<class T> bool gerater<T>                    大于
tmplate<class T> bool gerater_equal<T>              大于等于
tmplate<class T> bool less<T>                       小于
tmplate<class T> bool less_equal<T>                 小于等于

其中最常用的就是下面这两个

tmplate<class T> bool gerater<T>                    大于
tmplate<class T> bool less<T>                       小于

less<T>是各种模板函数和模板类的默认比较函数,从小到大升序排序

适用范围:

通常内置关系仿函数用于基本类型的比较,主要是用起来比较方便

模板函数和模板类都适用,但是参数的形式是有区别的

 

比如用sort()函数对数组排序  (模板函数)

bool cmp(int v1,int v2)
{
  return v1>v2;    
}

int s[]={15,17,5,7};
int n=4;

sort(s,s+n,cmp);  
//sort(s,s+n,greater<int>());

比较参数为函数名,实际上自定义比较函数cmp的作用根greater<T>是一样的

但是为什么上面调用的是cmp不加括号的,而下面调用的greater<int>()却是加括号的呢?

其实很简单,上面提到过模板函数需要的比较参数是函数名,而greater<T>就是一个模板类,在后面加个括号就相当于生成一个匿名的对象,因为其内部重载了小括号所以又称之为函数对象或者仿函数,其对象加括号可以像函数一样来使用,所以也可以把那个对象(匿名)看作一个函数名。ps:不是没有名字吗怎么还能当作函数名?这个是实参,形参有名字就行了!!

用set存储元素   (模板类)

class cmp{
public:
bool operator()(int v1,int v2){
return v1>v2;
}
};
set<int,cmp>set
={15,17,7,5};
//  set<int,greater<int>>set={15,17,7,5};
// 17 15 7 5

模板类中需要的比较参数是类型名,所以只要将类型名传入就行了

 

自定义函数对象(仿函数)

例子上面已经写了

适用范围:

适用于所有类型(基本类型和自定义类型)

适用于所有情况(模板函数和模板类),只是在调用时注意模板函数和模板类所需要的参数形式不同!!(第n次重复)

万金油了属于是,任何情况都可以用

自定义比较函数cmp()

例子在上面已经写了

适用范围:

适用于所有类型 (基本类型和自定义类型),毕竟参数是自己写的嘛

适用于模板函数(参数需要函数名)不适用于模板类(参数需要类型名)

 

重载'<'

如果要重载比较符来改变排序规则,只能重载'<'而不能重载'>'

其实要理解也简单,主要是c++中的默认排序就是 less('<'),你如果重载'>'   函数和类内部压根没用'>',所以重载了也没用,哪怕最后'<'执行的排序结果是从大到小那也只能重载'<'

适用范围:

适用于自定义类型,不适用于基本类型,如果问什么,那我只能说2不可能小于1!

适用于所有情况  (模板函数和模板类),对于重载过'<'的类型,因为函数和类里面调用的就是'<'所以此时并不需要显式的传参

#include <bits/stdc++.h>
using namespace std;

struct Point
{
    int x, y;
    Point() {}
    Point(int a, int b) : x(a), y(b) {}
};
//升序
bool operator<(const Point &p1, const Point &p2)
{
    if (p1.x == p2.x)
        return p1.y < p2.y;
    else
        return p1.x < p2.x;
}
//降序
/* bool operator<(const Point &p1, const Point &p2)
{
    if (p1.x == p2.x)
        return p1.y > p2.y;
    else
        return p1.x > p2.x;
} */

void test01()
{
    set<Point> set = {{7, 5}, {5, 7}, {17, 15}, {15, 17}};
    vector<Point> v = {{7, 5}, {5, 7}, {17, 15}, {15, 17}};
cout
<< "set:" << endl; for (auto i : set) cout << i.x << ' ' << i.y << endl;
cout
<< "vector:" << endl; sort(v.begin(), v.end());//排序 for (auto i : v) cout << i.x << ' ' << i.y << endl; } int main() { test01(); return 0; }

执行结果:

 

 

有任何问题欢迎指出!

讲的不是很详细,不懂dd

 

posted @ 2022-03-19 17:29  深情的山鸡  阅读(1483)  评论(1编辑  收藏  举报