C++中std::sort/std::stable_sort/std::partial_sort的区别及使用
某些算法會(huì)重排容器中元素的順序,如std::sort。調(diào)用sort會(huì)重排輸入序列中的元素,使之有序,它默認(rèn)是利用元素類型的<運(yùn)算符來(lái)實(shí)現(xiàn)排序的。也可以重載sort的默認(rèn)排序,即通過(guò)sort的第三個(gè)參數(shù),此參數(shù)是一個(gè)謂詞(predicate)。
??????? 謂詞是一個(gè)可調(diào)用的表達(dá)式,其返回結(jié)果是一個(gè)能用作條件的值,即返回一個(gè)bool類型的值。標(biāo)準(zhǔn)庫(kù)算法所使用的謂詞分為兩類:一元謂詞(unary predicate,只接受單一參數(shù))和二元謂詞(binary predicate,有兩個(gè)參數(shù))。接受謂詞參數(shù)的算法對(duì)輸入序列中的元素調(diào)用謂詞。因此,元素類型必須能轉(zhuǎn)換為謂詞的參數(shù)類型。
??????? 接受一個(gè)二元謂詞參數(shù)的sort版本用這個(gè)謂詞代替<來(lái)比較元素。
??????? std::sort:對(duì)給定區(qū)間所有元素進(jìn)行排序。
??????? std::stable_sort:對(duì)給定區(qū)間所有元素進(jìn)行穩(wěn)定排序,穩(wěn)定排序算法能夠維持相等元素的原有順序。
??????? std::partial_sort:對(duì)給定區(qū)間所有元素進(jìn)行部分排序。
??????? 當(dāng)容器中的元素是一些標(biāo)準(zhǔn)類型(如int、string)時(shí),可以直接使用函數(shù)模板。但其元素是自定義類型或者需要按照其它方式排序時(shí),需要自己來(lái)實(shí)現(xiàn),有兩種方法:一種是自己寫比較函數(shù),另一種是重載類型操作符”<”。std::sort/std::stable_sort/std::partial_sort中最后一個(gè)參數(shù)可以是函數(shù)指針類型或函數(shù)對(duì)象類型。
??????? std::sort采用類似快速排序算法,復(fù)雜度為N*log2(N);std::stable_sort采用類似歸并排序,復(fù)雜度為N*log2(N);std::partial_sort采用類似堆排序,復(fù)雜度為N*log(M)。但是在cplusplus中并沒(méi)有說(shuō)明每種sort采用的是具體哪種排序算法。
??????? std::sort:Sort elements in range, Sorts the elements in the range [first,last) into ascending order. The elements are compared using operator< for the first version, and comp for the second. Equivalent elements are not guaranteed to keep their original relative order (see stable_sort).
??????? std::stable_sort: Sort elements preserving order of equivalents. Sorts the elements in the range[first,last) into ascending order, like sort, but stable_sort preserves the relative order of the elements with equivalent values.
??????? std::partial_sort:Partially sort elements in range. Rearranges the elements in the range [first,last), in such a way that the elements before middle are the smallest elements in the entire range and are sorted in ascending order, while the remaining elements are left without any specific order.
下面是從其他文章中copy的測(cè)試代碼,詳細(xì)內(nèi)容介紹可以參考對(duì)應(yīng)的reference:
#include "sort1.hpp"
#include <iostream>
#include <algorithm> // std::sort
#include <functional> // std::greater
#include <vector>
#include <array>
#include <string>///
// reference: http://www.cplusplus.com/reference/algorithm/sort/
static bool myfunction(int i, int j) { return (i < j); }static struct myclass {bool operator() (int i, int j) { return (i < j); }
} myobject;int test_sort_1()
{int myints[] { 32, 71, 12, 45, 26, 80, 53, 33 };std::vector<int> myvector(myints, myints + 8); // 32 71 12 45 26 80 53 33// using default comparison (operator <):std::sort(myvector.begin(), myvector.begin() + 4); //(12 32 45 71)26 80 53 33// using function as compstd::sort(myvector.begin() + 4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)// using object as compstd::sort(myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)// print out content:std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';myvector.assign(myints, myints + 8);std::sort(myvector.begin(), myvector.end(), std::greater<int>()); // descending is to use std::greater()std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';// use std::sort to sort an array in C++11: std::begin/std::endstd::sort(std::begin(myints), std::end(myints));for (int i = 0; i < 8; ++i) {std::cout << " " << myints[i];}std::cout << "\n";return 0;
}/
// reference: https://www.codeproject.com/Articles/38381/STL-Sort-Comparison-Function
class Person_sort4 {
public:// default constructorPerson_sort4() : age(0) {}Person_sort4(int age, std::string name) {this->age = age; this->name = name;}bool operator<(const Person_sort4& rhs) { // define a member < operator for the Person classreturn this->age < rhs.age;}int age;std::string name;
};int test_sort_4()
{std::vector<Person_sort4> vecPerson;vecPerson.push_back(Person_sort4(24, "Calvin"));vecPerson.push_back(Person_sort4(30, "Benny"));vecPerson.push_back(Person_sort4(28, "Alison"));std::sort(vecPerson.begin(), vecPerson.end());for (size_t i = 0; i<vecPerson.size(); ++i)std::cout << vecPerson[i].age << ", " << vecPerson[i].name << std::endl;return 0;
}/
// reference: http://www.cplusplus.com/articles/NhA0RXSz/
struct Person_sort {// Left out making a constructor for simplicity's sake.std::string name;int age;std::string favoriteColor;
};// Sort Container by name function
static bool sortByName(const Person_sort &lhs, const Person_sort &rhs) { return lhs.name < rhs.name; }// Sort Container by age function
static bool sortByAge(const Person_sort &lhs, const Person_sort &rhs) { return lhs.age < rhs.age; }// Sort Container by favorite color
// We can just sort alphabetically and then it will group the color together.
static bool sortByColor(const Person_sort &lhs, const Person_sort &rhs) { return lhs.favoriteColor < rhs.favoriteColor; }// A global const variable to hold how many people to ask for input for.
const unsigned numberOfPeople = 2;int test_sort_2()
{using std::vector;using std::cout;using std::cin;using std::endl;using std::sort;using std::string;// Make a vector that holds 5 blank Person_sort Objectsvector<Person_sort> people { { "Tom", 23, "Red" }, {"Jim", 11, "Green"} };// This will ask for user input to populate the container// with 5 different indivuals.//for (vector<Person_sort>::size_type i = 0; i != numberOfPeople; ++i) {// cout << "Person_sort #" << i + 1 << " name: ";// cin >> people[i].name;// cout << "Person_sort #" << i + 1 << " age: ";// cin >> people[i].age;// cout << "Person_sort #" << i + 1 << " favorite color: ";// cin >> people[i].favoriteColor;//}//cout << "\n\n";// Sort by namesort(people.begin(), people.end(), sortByName);for (Person_sort &n : people)cout << n.name << " ";cout << endl;// Sory by agesort(people.begin(), people.end(), sortByAge);for (Person_sort &n : people)cout << n.age << " ";cout << endl;// Sort by colorsort(people.begin(), people.end(), sortByColor);for (Person_sort &n : people)cout << n.favoriteColor << " ";cout << endl;return 0;
}/
// reference: http://en.cppreference.com/w/cpp/algorithm/sort
int test_sort_3()
{std::array<int, 10> s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };// sort using the default operator<std::sort(s.begin(), s.end());for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a standard library compare function objectstd::sort(s.begin(), s.end(), std::greater<int>());for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a custom function objectstruct {bool operator()(int a, int b) const {return a < b;}} customLess;std::sort(s.begin(), s.end(), customLess);for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a lambda expression std::sort(s.begin(), s.end(), [](int a, int b) {return b < a;});for (auto a : s) {std::cout << a << " ";}std::cout << '\n';return 0;
}/
// reference: http://www.cplusplus.com/reference/algorithm/stable_sort/
static bool compare_as_ints(double i, double j)
{return (int(i)<int(j));
}int test_stable_sort_1()
{double mydoubles[] { 3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58 };std::vector<double> myvector;myvector.assign(mydoubles, mydoubles + 8);std::cout << "using default comparison:";std::stable_sort(myvector.begin(), myvector.end());for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';myvector.assign(mydoubles, mydoubles + 8);std::cout << "using 'compare_as_ints' :";std::stable_sort(myvector.begin(), myvector.end(), compare_as_ints);for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}/
// reference: http://en.cppreference.com/w/cpp/algorithm/stable_sort
struct Employee_sort {Employee_sort(int age, std::string name) : age(age), name(name) { }int age;std::string name; // Does not particpate in comparisons
};static bool operator<(const Employee_sort &lhs, const Employee_sort &rhs)
{return lhs.age < rhs.age;
}int test_stable_sort_2()
{std::vector<Employee_sort> v = {Employee_sort(108, "Zaphod"),Employee_sort(32, "Arthur"),Employee_sort(108, "Ford"),};std::stable_sort(v.begin(), v.end());for (const Employee_sort &e : v) {std::cout << e.age << ", " << e.name << '\n';}return 0;
}// reference: http://www.cplusplus.com/reference/algorithm/partial_sort/
int test_partial_sort_1()
{int myints[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };std::vector<int> myvector(myints, myints + 9);// using default comparison (operator <):std::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end());// using function as compstd::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end(), myfunction);// print out content:std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
GitHub: https://github.com/fengbingchun/Messy_Test
總結(jié)
以上是生活随笔為你收集整理的C++中std::sort/std::stable_sort/std::partial_sort的区别及使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: windows10 vs2013控制台工
- 下一篇: 分别用Eigen和C++(OpenCV)