一、partition 算法可以把满足特定条件的元素放在区间的前部,并且返回一个迭代器,指向第一个不满足条件的元素。
例如:我们要找出一个班级中成绩大于60分的学生,那么我们应该这样做。
bool IsPass(int a)
{
return a>=60;
}
vector<int>::iterator Pass = partition(record.begin(),record.end(),IsPass);
在此调用后,所有分数大于60分的学生都被放在record.begin()到Pass(不包括pass)之间,而分数小于60分的学生都被放在Pass到record.end()之间。
2.stable_partition
template <class BidirectionalIterator, class Predicate> BidirectionalIterator stable_partition ( BidirectionalIterator first, BidirectionalIterator last, Predicate pred );
Rearranges the elements in the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false, and, unlike function partition, grants the preservation of the relative order of elements within each group.
true在前,false在后, 不同于partition,可以保持相同元素的相对位置。比如,学生A和学生B的成绩相同,而且学生B在原来元素中的位置比学生A靠前。如果用partition进行排序,排序后学生A和学生B的位置就存在了不确定性,但是如果用stable_partition进行排序,那么就保持了相同元素的相对位置,也就是学生B仍然在学生A的前面。
This is generally implemented using a temporary buffer.
注意它的返回值:
An iterator that points to the first element of the second group of elements. For all the elements in this second group,pred return false.
返回第二组中的第一个元素
// stable_partition example #include <iostream> #include <algorithm> #include <vector> using namespace std; bool IsOdd (int i) { return (i%2)==1; } int main () { vector<int> myvector; vector<int>::iterator it, bound; // set some values: for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 bound = stable_partition (myvector.begin(), myvector.end(), IsOdd); // print out content: cout << "odd members:"; for (it=myvector.begin(); it!=bound; ++it) cout << " " << *it; cout << "\neven members:"; for (it=bound; it!=myvector.end(); ++it) cout << " " << *it; cout << endl; return 0; }
三、假设我要取一个班级里面排名前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就满足了我们上面所提的要求。它在排序的过程中可以保持相同元素的相对位置。这在某些情况下还是必须的。