众所周知,自定义排序方法繁多,bool表达式,拉姆达表达式,结构体内重载<表达式,结构体外重写cmp结构体,有的需要加const(内部外部),有的需要加(),还有的甚至需要加friend,本文总结一下只用struct cmp完成对各种有序数据结构的自定义排序,来减轻记忆量
1.最简单的sort函数
struct cmp{
bool operator()( const int& a , constint& b ) const{ //其中 const可以去掉,不过为了统一格式,这里统一加上了
return a < b ; //从小到大
}
} ;
调用,cmp后必须要加括号
sort( array , array+6 , cmp() ) ;
结构体类型
struct Node
{
int x;
int y;
int z;
Node() {}
Node(int x, int y, int z):x(x), y(y), z(z){} //赋值
};
struct cmp
{
/*bool operator() (const Node& a,const Node& b) //从大到小
{
return a.x<b.x;
}*/
bool operator() (const Node& a,const Node& b) const //从小到大
{
if (a.x == b.x) {
if(a.y == b.y) {
return a.z > b.z; // 第3顺序按z降序排列
}
return a.y > b.y; // 第2顺序按y降序排列
}
return a.x < b.x; // 第3顺序按x升序排列
}
};
//调用
int maxSize = 4;
Node node[maxSize] = {{1,5,9}, {2, 6, 10}, {2, 9, 8}, {2,9,3}};
sort (node, node + maxSize, cmp() );
输出
1 5 9
2 9 8
2 9 3
2 6
2.优先级队列
struct Node
{
int x;
Node() {}
Node(int x):x(x) {} //赋值
};
struct cmp
{
/*bool operator() (const Node& a,const Node& b) //从大到小
{
return a.x<b.x;
}*/
bool operator() (const Node& a,const Node& b) //从小到大
{
return a.x>b.x;
}
};
调用
priority_queue<Node,vector<Node>,cmp > p;
输出
for(int i=1; i<=5; i++)
p.push(Node(i));
cout<<"p = ";
while(!p.empty())
{
cout<<p.top().x<<' ';
p.pop();
}
cout<<endl;
//p1 = 1 2 3 4
pair类型可用于可sort排序的容器中,或者map,优先级队列,
struct cmp
{
bool operator()(const pair<int, int>&p1,const pair<int, int>& p2)
{
if(p1.first == p2.first) {
return p1.second < p2.second;
} else {
return p1.first > p2.first;
}
}
};
//调用
//vector
vector <pair<int, int> >ve;
sort(ve.begin(), ve.end(), cmp());
for(int i = 0; i < 3; i++) {
cout << ve[i].first << " " << ve[i].second << endl;
}
//set
set<pair<int, int> >se;
set <pair<int, int> ,cmp>ve;
ve.insert(make_pair(1,2));
ve.insert(make_pair(3,6));
ve.insert(make_pair(3,1));
for(auto &i : ve) {
cout << i.first << " " << i.second << endl;
}
//map
map <pair<int, int>,int ,cmp>mp;
mp.insert(pair<pair<int, int >, int>(make_pair(1,5), 9));
mp.insert(pair<pair<int, int >, int>(make_pair(2,6), 10));
mp.insert(pair<pair<int, int >, int>(make_pair(2,9), 8));
for(auto iter=mp.begin(); iter!=mp.end(); iter++)
cout<<iter->first.first<<" "<<iter->first.second<<" "<<iter->second<<endl;
return 0;
}
// 优先级队列
priority_queue<pair<int,int>, vector<pair<int,int> >, cmp >q;
q.push({7,8});
q.push({7,9});
q.push(make_pair(8,7));
while(!q.empty())
{
cout<<q.top().first<<" "<<q.top().second<<endl;
q.pop();
}
// 输出
7 9
7 8
8
set 类型
struct cmp{
bool operator()( const int& a , const int& b )const{
return a > b ; //从大到小
}
} ;
调用
set<int,cmp> s{3,5,7,4,8} ;
set<int,cmp>::iterator it = s.begin();
for( ; it!=s.end();it++)
printf("%d\n",*it);
//输出
8
5
4
map键值为自定义结构体类型
#include<iostream>
#include<map>
using namespace std;
struct Node
{
int x;
int y;
int z;
Node() {}
Node(int x, int y, int z):x(x), y(y), z(z){} //赋值
};
//自定义比较规则
//注意operator是(),不是<
struct cmp
{
bool operator() (const Node& a,const Node& b) const //从小到大
{
if (a.x == b.x) {
if(a.y == b.y) {
return a.z > b.z; // 第3顺序按z降序排列
}
return a.y > b.y; // 第2顺序按y降序排列
}
return a.x < b.x; // 第3顺序按x升序排列
}
};
int main()
{ int a = 0;
int maxSize = 4;
Node node[maxSize] = {{1,5,9}, {2, 6, 10}, {2, 9, 8}, {2,9,3}};
//注意此处一定要有Cmp,否则无法排序会报错
map<Node,int,cmp>mp;
for(int i = 0; i < 4; i++) {
a = rand()%4;
mp.insert(pair<Node,int>(node[i],a));
}
map<Node,int>::iterator iter;
for(iter=mp.begin(); iter!=mp.end(); iter++)
cout<<iter->first.x<<" "<<iter->first.y<<" "<<iter->first.z<<" "<<iter->second<<endl;
return 0;
}
如果允许键值重复,可以把map改成multimap,其他用法