C++,自定义sort排序算法,map(key和value分别如何排序),set,priority_queue 自定义存储顺序
就目前所利用的知识中,有两处用到了自定义排序算法。 第一个是sort函数;第二个是部分排序容器的建立,例如map,set,priority_queue。在此记录一些通用的方法,至于其他更多原理,等有时间在记录。在C++ STL中,对于 vector,有 sort 函数,可以对 vector 中的元素进行排序。注意,下面的例子, sort(vec.begin(), vec.end(), cmp())
·
在STL中,经常用到的排序有两处:
第一个是sort函数,容器要求是可以随机访问,像array,vector,deque,和普通数组。
第二个是部分排序容器的建立,例如map,set,priority_queue。
1、sort()函数
注意,下面的例子, sort(vec.begin(), vec.end(), cmp()),都加了括号,使用的是函数对象,更快。sort() 只对 array、vector、deque 和普通数组有支持。
1、对基本数据类型进行排序
1、默认方法
首先,sort() 函数,默认采用的是升序。less 是升序,greater 是降序。注意使用方法,其原型是函数对象的实现,因此注意写法。
vector<int> Vint = { 1,3,5,2,4,6 };
sort(Vint.begin(), Vint.end()); { 1,2,3,4,5,6 }
//sort(Vint.begin(), Vint.end(), less<int>()); { 1,2,3,4,5,6 }
sort(Vint.begin(), Vint.end(), greater<int>()); { 6,5,4,3,2,1 }
2、自定义方法,基本元素
struct shengxu{
bool operator()(int a, int b){
return a < b;
}
struct jiangxu{
bool operator()(int a, int b){
return a > b;
}
vector<int> Vint = { 1,3,5,2,4,6 }
sort(Vint.begin(), Vint.end(), shengxu()); { 1,2,3,4,5,6 }
sort(Vint.begin(), Vint.end(), jiangxu()); { 6,5,4,3,2,1 }
int N[] = { 1,3,5,2,4,6 };
sort(N, N+6, shengxu); { 1,2,3,4,5,6 }
// sort 函数第二个参数要指向要排序元素截至后的一个字符。
3、对复杂元素进行排序
struct node{
string name;
int age;
};
//先按name排序(升序),如果name相等,再按age排序(升序);
struct omp{
bool operator()(node& a, node& b){
if (a.string == b.string){
return a.age < b.age;
}
return a.string < b.string;
}
node N[3] = {{"a",10},{"a",5},{"b",5}}
sort(N, N+3, omp()); {{"a",5},{"a",10},{"b",5}}
vector<node> nn(N, N+3); //怎样用数组创建vector
sort(nn.begin(), nn.end(), omp()); {{"a",5},{"a",10},{"b",5}}
2、map,set
1、set容器为例
1、默认方法
set 容器默认的存储的是升序。
set<int> Sint = { 1,3,2 };
for (auto it = Sint.begin(); it != Sint.end(); it++)
cout << *it << " ";
{ 1,2,3 }
set<int, greater<int>> Sint = { 1,3,2 }; { 3,2,1 }
2、自定义
注意 set 排序的时候 ,函数要加 const
struct cmp{
bool operator()(int a, int b) const{
return a<b;
}
};
set<int,cmp> Sint = { 1,3,2 }; { 1,2,3 }
3、对复杂元素
struct node {
string name;
int age;
};
struct cmp {
bool operator() (node a, node b) const {
if (a.name != b.name)
return a.name < b.name;
return a.age < b.age;
}
};
int main()
{
set<node, cmp> se;
se.insert({ "a",10 });
se.insert({ "a",5 });
se.insert({ "b",5 });
for (auto i = se.begin(); i != se.end(); i++) {
cout << i->name << " " << i->age << endl;
}
return 0;
}
输出:
a 5
a 10
b 5
2、map容器
默认是对 key 值进行升序存储。
1、对 key 排序
1、对简单元素
默认是升序, less。
struct cmp{
bool operator() (int a, int b) const{
return a > b; //降序
}
};
int main()
{
map<int,int,cmp> mp;
mp[1] = 10;
mp[4] = 3;
mp[2] = 6;
for(auto i = mp.begin(); i != mp.end(); i++) {
cout << i->first << " " << i->second << endl;
}
return 0;
}
输出// 4 3
2 6
1 10
对key 进行降序
2、对结构体等复杂元素
struct node {
string name;
int age;
};
struct cmp {
bool operator() (node a, node b) const {
if (a.name != b.name)
return a.name < b.name;
return a.age < b.age;
}
};
map<node, int, cmp> ma;
ma.insert({ { "a",10 } , 1 });
ma.insert({ { "a",5 } , 2 });
ma.insert({ { "b",5 } , 3 });
for (auto i = ma.begin(); i != ma.end(); i++) {
cout << (i->first).name << " " << (i->first).age << " " << i->second << endl;
}
输出:
a 5 2
a 10 1
b 5 3
2、对 value 排序
虽然不能直接用sort对map进行排序,那么我们可不可以迂回一下,把map中的元素放到序列容器(如vector)中,然后再对这些元素进行排序。
在此,要知道一个 数据,pair 数据类型。
template <class T1, class T2> struct pair;
pair <string, int> pair1("STL教程", 20);
pari1.first = "STL教程";
pari1.second = 20;
map<string,int> ma;
ma.insert(pari1);
struct node {
string name;
int age;
};
struct cmp1 {
bool operator()(pair<node, int> a, pair<node, int> b) {
return a.second > b.second;
}
};
map<node, int, cmp> ma;
ma.insert({ { "a",10 } , 1 });
ma.insert({ { "a",5 } , 2 });
ma.insert({ { "b",5 } , 3 });
vector<pair<node, int>> v(ma.begin(), ma.end());
sort(v.begin(), v.end(), cmp1());
for (auto i : v) {
cout << (i.first).name << " " << (i.first).age << " " << i.second << endl;
}
输出:
b 5 3
a 5 2
a 10 1
3、 priority_map
1、默认从大到小
int main()
{
//创建一个空的priority_queue容器适配器
std::priority_queue<int>values;
//使用 push() 成员函数向适配器中添加元素
values.push(3);//{3}
values.push(1);//{3,1}
values.push(4);//{4,1,3}
values.push(2);//{4,2,3,1}
//遍历整个容器适配器
while (!values.empty())
{
//输出第一个元素并移除。
std::cout << values.top()<<" ";
values.pop();//移除队头元素的同时,将剩余元素中优先级最大的移至队头
}
return 0;
}
输出:
4 3 2 1
2、自定义
struct cmp {
bool operator()(int a, int b) const {
return a > b;
}
};
int main()
{
int N[] = { 1,3,2,4 };
priority_queue<int,vector<int>,cmp> myque(N,N+4);
while (!myque.empty()) {
cout << myque.top() << endl;
myque.pop();
}
return 0;
}
输出: 1 2 3 4
3、对结构体排序
struct node{
int age;
string name;
node(int a, string n):age(a),name(n){}
};
struct cmp {
//先对年龄升序,年龄一样,对名字升序,注意是 >
bool operator() (node& a, node& b) {
if (a.age != b.age)
return a.age > b.age;
return a.name > b.name;
}
};
int main()
{
priority_queue<node, vector<node>, cmp> pque;
pque.push(node(15,"zhangsan"));
pque.push(node(13,"lisi"));
pque.push(node(15,"lisi"));
while(!pque.empty()) {
cout << pque.top().age << " " << pque.top().name << endl;
pque.pop();
}
return 0;
}
//输出:
13 lisi
15 lisi
15 zhangsan
4、总结
- priority_queue 入队时候,排序的表示 和 其余不一样,刚好相反。
- 使用函数对象 自己定义排序规则时, set 和 map 需要加 const;
- priority_queue 在加自己定义的优先级时候,需要将第二个参数也声明;
- 在添加自定义排序规则时,sort(v.begin(),v.end(), cmp()); set<int, cmp> se;
更多推荐
已为社区贡献1条内容
所有评论(0)