Table of Contents
1 partial_sort
partial sort 能夠進行部分排序,例如,僅 按順序排出 某個容器中的前 20 名: css
bool qualityCompare(const Widget& lhs, const Widget& rhs); partial_sort(widgets.begin(), widgets.begin()+20, widgets.end(), qualityCompare);
2 nth_element
與 partial_sort 相似, nth_element 也用於部分排序,但它只保證指定的排名前 N 個元素會存放到容器的前N,但這前 N 個元素之間的順序不必定。更重要的是,它能夠保證,若是咱們對容器進行徹底排序,排在 N 位置的那個元素必定和 nth_element 排序後 N 位置的元素相同(等值): java
nth_element(widgets.begin(), widgets.begin()+20, widgets.end(), qualityCompare);
此外, nth_element 能夠方便地計算出指定容器中指定排名的元素: ios
vector<Widget>::size_type goalOffset = 0.21 * widgets.size(); nth_element(begin, begin+goalOffset, end, qualityCompare);
3 stability
對於任意的等價對象 A 與 B ,若是 A 在容器中的位置比 B 靠前,且排序後 A 的位置仍然在 B 以前,則稱該排序算法爲穩定的 (stable) 。 partial_sort 和 nth_element 都不是穩定的,但算法 stable_sort 能夠保證這一點。 c++
4 partition
partition 能夠將對 Sequence Container 進行排序,排序完成後返回的迭代器指向知足條件的最後一個元素: 算法
bool HasAcceptableQuality(const Widget& w); vector<Widget>::iterator goodEnd = partition(widgets.begin(), widgets.end(), HasAcceptableQuality);
當上述表達式完成以後,返回的 goodEnd 指向了知足 HasAcceptableQuality 的最後一個元素,算法不保證 goodEnd 以前的元素順序,但 stable_partition 能夠保證 stability. sql
5 總結
- 須要對 vector, string, dequeu, array 進行徹底排序 \(\rightarrow sort/stable\_sort\)
- 須要從 vector, string, dequeu, array 中獲取排好序的前 N 個元素:\(\rightarrow partial\_sort\)
- 須要從 vector, string, dequeu, array 中獲取無序的前 N 名或者指定的第 N 名: \(\rightarrow nth\_element\)
- 須要從順序容器中獲取符合某種條件的全部元素: \(\rightarrow partition/stable\_partition\)
- 須要對 List 進行排序,最好使用 List 自己的相關函數,或者將 List 轉換成 vector 再使用 STL 算法。
上述各類算法的效率: bash
\(partition > stable\_partition > nth_element > partial\_sort > sort > stable\_sort\) less
#include <vector> #include <algorithm> #include <stdio.h> #include <string> #include <iostream> #include <fstream> #include <iterator> #include <stdlib.h> #include <sys/time.h> using namespace std; #define N 1000000 typedef unsigned int uint32; static inline uint32 current_time_ms() { struct timeval tv; return (gettimeofday(&tv, NULL) != -1) ? \ tv.tv_sec * 1000 + tv.tv_usec / 1000 : 0; } #define show(s,e) copy(s, e, os); cout << endl ; #define nth(v, N) *(v.begin()+N-1) bool PartitionCond(int& i) { return i < 50; } int main(int argc, char *argv[]) { srand(time(NULL)); vector<int> v(N); for (int i = 0; i < N; ++i) { v[i] = i; } random_shuffle(v.begin(), v.end()); ostream_iterator<int> os(cout, " "); cout << "Original array = " << endl; show(v.begin(),v.begin()+21); cout << "Partial_sort for 20 elements... " << endl; vector<int> v1(v); uint32 ts = current_time_ms(); partial_sort(v1.begin(), v1.begin()+21, v1.end(), less<int>()); cout << "time = " << current_time_ms() - ts << endl; show(v1.begin(),v1.begin()+21); cout << "nth_element of the 20th elements... " << endl; vector<int> v2(v); ts = current_time_ms(); nth_element(v2.begin(), v2.begin()+20, v2.end(),less<int>()); cout << "time = " << current_time_ms() - ts << endl; show(v2.begin(),v2.begin()+21); cout << "v1[19] = " << nth(v1, 21) << endl; cout << "v2[19] = " << nth(v2, 21) << endl; vector<int>v5(v); sort(v5.begin(), v5.end()); if (nth(v5, 21) == nth(v2, 21)) { cout << "nth_element works! " << endl; } else { cout << "nth_element is not working correctly! " << endl; } cout << "Testing partition... " << endl; vector<int> v3(v); ts = current_time_ms(); vector<int>::iterator i1 = partition(v3.begin(), v3.end(), PartitionCond); cout << "Time cost = " << current_time_ms() - ts << endl; show(v3.begin(), i1); cout << "Testing stable_partition... " << endl; vector<int> v4(v); ts = current_time_ms(); vector<int>::iterator i2 = stable_partition(v4.begin(), v4.end(), PartitionCond); cout << "Time cost = " << current_time_ms() - ts << endl; show(v4.begin(), i2); return 0; }