在此之前,我所知道的STL中的排序算法只有sort.
但是,经过实践发现单单sort并不是那么够用的。
事实上, STL中的算法分为好多种。
1.partition
2.stable_partition
3.nth_element
4.partial_sort
5.sort
6.stable_sort
下面我们来讲一下他们的区别所在。
一、partition算法可以把满足特定条件的元素放在区间的前部,并且返回一个迭代器,指向第一个不满足条件的元素。
例如:我们要找出一个班级中成绩大于60分的学生,那么我们应该这样做。
bool IsPass(int a)
{
return a>=60;
}
vector<int>::iterator Pass = partition(record.begin(),record.end(),IsPass);
在此调用后,所有分数大于60分的学生都被放在record.begin()到Pass之间,而分数小于60分的学生都被放在Pass到record.end()之间。
二、但是如果我们想在partition的排序过程中,保持相同元素的相对位置,那么我们就应该使用stable_partition.
比如,学生A和学生B的成绩相同,而且学生B在原来元素中的位置比学生A靠前。
如果用partition进行排序,排序后学生A和学生B的位置就存在了不确定性,但是如果用stable_partition进行排序,那么就保持了相同元素的相对位置,也就是学生B仍然在学生A的前面。
三、假设我要取一个班级里面排名前20名的学生,并且对前20名的学生进行排序。那么用sort是比较浪费时间的。sort是对所有的学生进行排序,而我们需要的只是对前20名的学生进行排序。那么我们就可以考虑使用partial_sort来进行操作。
partial_sort是一种部分排序的算法,它只取指定条件的前n个元素进行排序。
具体使用方法如下:
bool Compare(int a, int b)
{
return a>b;
}
partial_sort(record.begin(), record.begin()+20, record.end(), Compare);
四、如果我们只要知道前20名是哪几个人就可以了,而不需要知道他们的顺序。那么我们就可以使用nth_element来解决问题,耗费的时间会少于partial_sort。
nth_element是把符合条件的前n个放在前端。
使用方法如下:
bool Compare(int a, int b)
{
return a>b;
}
nth_element(record.begin(),record.begin()+19,record.end(),Compare);
要注意的是nth_element的第二个参数指向的是符合条件的最后一个元素。
而partial_sort的第二个参数指向的是符合条件的元素的后一个元素。
当区间元素个数不大于32 时,直接做一次全排序,只有元素个数足够多时,才采用常规的线性复杂度算法。
nth_element还有个特殊的用途,就是可以用来查找一个区间的中间值,或者某个特定百分比上的值。
例子如下:
bool Compare(int a, int b)
{
return a>b;
}
vector<int>::iterator Pos;
//查找区间中成绩处在20%的元素。
Pos = record.begin() + record.size()*0.2;
nth_element(record.begin(), Pos, record.end(), Compair);
Pos指向的就是成绩处在20%的元素。
五、sort是我们最常用的排序算法,但是大家是否知道它的一个重要特性?
也就是当碰到几个相同元素的时候,sort 是如何处理他们的。
事实上,sort如果碰到几个相同的元素,为了提高算法的速度,就没有保持相同元素的相对位置。
但是有时候,保持相同文件的相对位置对我们至关重要,那么我们就需要考虑用其他的排序算法来实现了。
六、stable_sort就满足了我们上面所提的要求。它在排序的过程中可以保持相同元素的相对位置。这在某些情况下还是必须的。