在cpp中我们常见的容器有string,vector,deque,queue,set(multiset),list,map(multimap),stack这几个。其中最常用的就是vector,list,map,所以这里就以这三个容器的排序为例进行分享我自己的想法。
这三个容器中的map特别一点,具有自动排序功能,但也仅是升序,下面会将如何实现降序等。
方法一:容器自带的排序功能--sort
这个功能只有list容器具有,并且默认为升序。
void test1()
{
list<int>L = { 1,5,3,7,9,2,4,8,6 };
for (auto i : L) { cout << i << " "; }
cout << endl;
L.sort();//开始排序
for (auto i : L) { cout << i << " "; }
cout << endl;
}
可是,如果我想降序呢?这里有两种方法:
1.同时使用list另外一种接口reverse:
void test1()
{
list<int>L = { 1,5,3,7,9,2,4,8,6 };
for (auto i : L) { cout << i << " "; }
cout << endl;
L.sort();
for (auto i : L) { cout << i << " "; }
cout << endl;
L.reverse();//该接口的功能是将容器的数据逆序
for (auto i : L) { cout << i << " "; }
cout << endl;
}
2.使用自定义规则的函数:
其实sort后面的()里面是可以放内容的,可以放一个返回bool类型的函数,用来进行自定义排序,具体操作如下:
bool compare(int a,int b)
{
//这里传进来的a,b是容器中一前一后两个数
//返回值a>b成立,就表明是要求降序
return a > b;
}
void test1()
{
list<int>L = { 1,5,3,7,9,2,4,8,6 };
L.sort(compare);//这里传进一个函数名就行了
for (auto i : L) { cout << i << " "; }
cout << endl;
}
在对自定义类型数据进行排序时,可以在compare函数里面使用if语句进行进一步的细节排序。
方法二:使用sort算法
在包含<algorithm>头文件后,可以使用sort对容器进行排序。
注意,这个sort的用法,和上面的容器自带的sort接口是不同的。区别如下:
void test2()
{
list<int>L = { 1,5,3,7,9,2,4,8,6 };
L.sort(compare);
vector<int>v = { 1,7,4,6,9,3,2,5,8 };
sort(v.begin(), v.end());
}
这里大家可能会疑问我为什么没有对list使用sort算法作为例子。
注意,sort并不是一个内部连续的容器,而是由多个数据域和指针域结合一起的结点相连而成,而sort算法只能对连续的数据进行排序。
这里以vector为例使用sort算法:
void test2()
{
vector<int>v = { 1,7,4,6,9,3,2,5,8 };
for (auto i : v) { cout << i << " "; }
cout << endl;
sort(v.begin(), v.end());//放进想要排序的区间,默认升序
for (auto i : v) { cout << i << " "; }
cout << endl;
}
如果想要降序呢?
bool compare(int a,int b)
{
//这里传进来的a,b是容器中一前一后两个数
//返回值a>b成立,就表明是要求降序
return a > b;
}
void test2()
{
vector<int>v = { 1,7,4,6,9,3,2,5,8 };
for (auto i : v) { cout << i << " "; }
cout << endl;
sort(v.rbegin(), v.rend());//1.可以把区间进行倒置
for (auto i : v) { cout << i << " "; }
cout << endl;
sort(v.begin(), v.end(),compare);//2.在这里放进表示排序规则的函数名
for (auto i : v) { cout << i << " "; }
cout << endl;
}
方法三:使用容器本身的规则
这中方法是仅用于map,set的,他们本身在放入数据时就会自动排序,且为升序。但也能进行自定义排序。
这里以map容器为例:
class compare
{
public:
bool operator()(int a, int b) const
//这里要加const,不然会出错,具体原因尚未清楚。。。
{
return a > b;
}
};
void test3()
{
map<int,int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(7, 20));
m.insert(pair<int, int>(5, 90));
m.insert(pair<int, int>(3, 40));
m.insert(pair<int, int>(4, 70));
m.insert(pair<int, int>(6, 60));
for (auto i : m){cout << i.first << " " << i.second << endl;}
//map会根据key值进行排序
//如果key值是一个字符,那会就会根据(首)字符的ASCII进行排序
cout << "-------------------" << endl;
//方法一:使用函数对象
//注意要在初始化时使用
map<int, int, compare>m2;//这里需要放入仿函数的类名
m2.insert(pair<int, int>(1, 10));
m2.insert(pair<int, int>(7, 20));
m2.insert(pair<int, int>(5, 90));
m2.insert(pair<int, int>(3, 40));
m2.insert(pair<int, int>(4, 70));
m2.insert(pair<int, int>(6, 60));
for (auto i : m2) { cout << i.first << " " << i.second << endl; }
cout << "------------------" << endl;
//方法三:使用关系仿函数greater<>
map<int, int, greater<int>>m3;
m3.insert(pair<int, int>(1, 10));
m3.insert(pair<int, int>(7, 20));
m3.insert(pair<int, int>(5, 90));
m3.insert(pair<int, int>(3, 40));
m3.insert(pair<int, int>(4, 70));
m3.insert(pair<int, int>(6, 60));
for (auto i : m3) { cout << i.first << " " << i.second << endl; }
}
方法四:手动排序
可以直接来硬的,冒泡排序、选择排序什么的安排上。。。
但我个人认为没那必要。。。
以上就是个人对容器排序方法的总结,若有错误,欢迎指出!