STL各容器的排序问题
1.在STL中,string,deque,vector 中未内置排序算法,可以通过algorithm中的sort()进行排序,
可以通过修改重载cmp()比较函数实现不同要求的排序。
2.在STL中,set,map中会自动排序,且为正序,若需排序,要重载STL的排序算法,
但是不能直接通过algorithm中的sort()进行排序(有些可以用sort,只是比较麻烦)
3.在STL中,list自带排序算法,可以通过l.list()调用,若需排序,要重载STL的排序算法,
并调用l.list(cmp)。
1.关于string/deque/vector中重载排序的问题
(1)在STL中,string/deque/vector未内置排序算法,通常通过algorithm中的sort()进行排序,
sort默认为增序排列,即:
若待排序数据为整型、字符型,按从小到大顺序排列;
若待排序数据为字符、字符串型,按字典序排列。
实例如下:
#include<iostream>
#include<vector>
#include<algorithm> <span style="font-family: Arial, Helvetica, sans-serif;">//sort函数头文件</span>
using namespace std;
int main()
{
vector<int> v;
v.push_back(3);
v.push_back(1);
v.push_back(2);
sort(v.begin(), v.end()); //实现排序,正序排列
for(int i=0; i<v.size(); i++)
cout<<v[i]<<" ";
cout<<endl;
return 0;
}
(2)其他排序方式的实现
对于非增序排列,若要实现,需重载sort函数的比较函数cmp,下面以减序为例:
#include<iostream>
#include<vector>
#include<algorithm> <span style="font-family: Arial, Helvetica, sans-serif;">//sort函数头文件</span>
using namespace std;
bool cmp(int a, int b) //重载排序函数cmp
{
return a>b;
}
int main()
{
vector<int> v;
v.push_back(3);
v.push_back(1);
v.push_back(2);
sort(v.begin(), v.end(), cmp); <span style="font-family: Arial, Helvetica, sans-serif;">//实现排序,按cmp函数规则排列</span>
for(int i=0; i<v.size(); i++)
cout<<v[i]<<" ";
cout<<endl;
return 0;
}
当然,对于减序排列算法实现上也可以用倒序进行输出。
(3)各种排序
这里给一个采用复杂排序的ACM水题作为实例:
题目大致是:输入若干行由0和1组成的串,将这些串排序输出。
排序规则是:首先按长度排序,长度相同时,按1 的个数多少进行排序,
1 的个数相同时再按ASCII 码值排序。
算法实现如下(过程有简化):
……
#include<algorithm>
using namespace std;
bool cmp(string s1, string s2)
{
int t1 = count(str1.begin(),str1.end(), '1');
int t2 = count(str2.begin(),str2.end(), '1');
if(s1.length() !=s2.length())
{
return s1.length() <s2.length();
}
return (t1 != t2 ? t1 < t2: s1 < s2);
}
int main()
{
……
sort(s.begin(), s.end(), cmp);
……
return 0;
}
2.关于关于set,map的排序的问题
(1) 在STL中,set/map内置有排序算法,默认为增序排列,set和map容器是基于红黑树的数据结构,
在插入元素时,会自动调整红黑树对元素进行排列,其中需要注意的是,
map<Key, Value>的排列是针对其Key值而非其Value值。
实例如下:
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<char, int> m;
for(int i=0; i<10; i++)
m['A'+i] = 10-i;
map<char, int>::iteratorit;
for(it=m.begin(); it!=m.end();it++)
cout<<(*it).first<<":"<<(*it).second<<endl;
cout<<endl;
return 0;
}
(2)其他排序方式的实现
对于非增序排列,若要实现,需重载内置的比较函数cmp,下面以减序为例,编写比较函数有两种方法。
①如果元素不是结构体,那么,可以编写比较函数。
#include<iostream>
#include<map>
using namespace std;
struct cmp
{
bool operator()(const int &a,const int &b)
{
return a>b;
}
};
int main()
{
map<char, int, cmp> m; //以键char的值进行降序排序
for(int i=0; i<10; i++)
m['A'+i] = 10-i;
map<char, int, cmp>::iterator it;
for(it=m.begin(); it!=m.end(); it++)
cout<<(*it).first<<":"<<(*it).second<<endl;
cout<<endl;
return 0;
}
②如果元素是结构体,那么,可以直接把比较函数写在结构体内。
#include<iostream>
#include<map>
using namespace std;
struct Info
{
char letter;
bool operator < (const Info &a) const
{
return a.letter<letter;
}
};
int main()
{
map<Info, int> m; //以键Info的score的值进行降序排序
Info info;
for(int i=0; i<10; i++)
{
info.letter = 'A'+i;
m = 10-i;
}
map<Info, int>::iterator it;
for(it=m.begin(); it!=m.end(); it++)
cout<<(*it).first.letter<<":"<<(*it).second<<endl;
cout<<endl;
return 0;
}
3.关于list的排序
(1)在STL中,set/map内置有排序算法,默认为增序排列,实例如下:
#include<iostream>
#include<list>
using namespace std;
bool cmp(const int &a, const int &b)
{
returna>b;
}
int main()
{
list<int> l; //以键Info的score的值进行降序排序
for(inti=0; i<10; i++)
l.push_back(10-i);
l.sort(cmp);
list<int>::iterator it;
for(it=l.begin(); it!=l.end(); it++)
cout<<*it<<" ";
cout<<endl;
return 0;
}
(2)其他排序方式
List是链表,结构较为复杂,一般情况下,再设计算法时发现需要排序,尽量不要采用list,
可以尝试vector。以减序为例,如下:
#include<iostream>
#include<list>
using namespace std;
bool cmp(const int &a, const int&b)
{
return a>b;
}
int main()
{
list<int>l;
for(int i=0; i<10; i++)
l.push_back(i);
l.sort(cmp); //实现降序排序
list<int>::iterator it;
for(it=l.begin(); it!=l.end(); it++)
cout<<*it<<" ";
cout<<endl;
return 0;
}
此外,还有一些方法,例如大多数情形下algorithm下的sort都可以进行,还有就是可以
把你所要排序的数据结构封装到map里面,形成map<int,vector<class>>,亦或者将你的
数据结构中的数据用map进行映射处理。