C++中sort函數(shù)的基礎(chǔ)入門使用教程
前言
STL主要包含容器,迭代器,算法三塊內(nèi)容,用戶可以對(duì)容器進(jìn)行一系列的操作,比如遍歷和計(jì)算,而STL提供的迭代器和容器完美地提供了這樣的接口。其中std::vector是最常用的容器之一,vector是一個(gè)模板類,定義在命名空間namespace下,使用vector需要在包含相關(guān)頭文件。今天主要講解對(duì)vector的排序的使用。
sort類函數(shù):
| 函數(shù)名 | 功能描述 |
|---|---|
| sort | 對(duì)給定區(qū)間所有元素進(jìn)行排序 |
| stable_sort | 對(duì)給定區(qū)間所有元素進(jìn)行穩(wěn)定排序 |
| partial_sort | 對(duì)給定區(qū)間所有元素部分排序 |
| partial_sort_copy | 對(duì)給定區(qū)間復(fù)制并排序 |
| nth_element | 找出給定區(qū)間的某個(gè)位置對(duì)應(yīng)的元素 |
| is_sorted | 判斷一個(gè)區(qū)間是否已經(jīng)排好序 |
| partition | 使得符合某個(gè)條件的元素放在前面 |
| stable_partition | 相對(duì)穩(wěn)定的使得符合某個(gè)條件的元素放在前面 |
需要頭文件<algorithm>
語(yǔ)法描述:sort(begin,end,cmp),cmp參數(shù)可以沒(méi)有,如果沒(méi)有默認(rèn)非降序排序。
常見(jiàn)的排序算法有快速排序、冒泡排序、歸并排序等。STL中sort函數(shù)的實(shí)現(xiàn)跟STL的版本有關(guān),而往往sort函數(shù)是由多種排序算法混合而成的。
1. vector元素為內(nèi)置數(shù)據(jù)類型
STL中sort函數(shù)的使用方法如下,默認(rèn)對(duì)容器進(jìn)行從小到大的排序。
#include <vector> // std::vector
#include <algorithm> // std::sort
int main(){
std::vector<int> vi{2, 0, 1, 8, 1, 2, 1, 5};
std::sort(vi.begin(), vi.end()); // 相當(dāng)于 std::sort(vi.begin(), vi.end(), std::less<int>());
for (int i = 0; i < vi.size(); ++i) {
printf("%d ", vi[i]);
}
printf("\n");
// output: 0 1 1 1 2 2 5 8
當(dāng)然也可以指定對(duì)容器進(jìn)行從大到小的排序:
#include <vector> // std::vector
#include <algorithm> // std::sort
int main(){
std::vector<int> vi{2, 0, 1, 8, 1, 2, 1, 5};
std::sort(vi.begin(), vi.end(), std::greater<int>());
for (int i = 0; i < vi.size(); ++i) {
printf("%d ", vi[i]);
}
printf("\n");
// output: 8 5 2 2 1 1 1 0
2. vector元素為用戶自定義數(shù)據(jù)類型
如果vector內(nèi)的元素為用戶自定義類型,并且用戶想要按照自定義類型的某些組合特性進(jìn)行排序。先來(lái)看看sort函數(shù)的定義:
template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
其中前兩個(gè)參數(shù)為迭代器類型,第三個(gè)參數(shù)為比較函數(shù)。下面的例子中,類Character擁有兩個(gè)屬性,age_ 和 name_,這里為了簡(jiǎn)單起見(jiàn),變量均為public?,F(xiàn)在需要對(duì)一個(gè)元素類型為Character的vector進(jìn)行按照Character的 age_ 從小打到進(jìn)行排序。
class Character {
public:
Character(int n, string s) : age_(n), name_(s) {}
int age_;
string name_;
};
class Compare {
public:
bool operator() (Character* ca, Character* cb) {
return ca->age_ < cb->age_;
}
};
int main(){
vector<Character*> vc{new Character(1, "sasaki"), new Character(2, "nozomi"), new Character(1, "satchel"), new Character(6, "qingtian")};
sort(vc.begin(), vc.end(), Compare());
for (int i = 0; i < vc.size(); ++i) {
printf("%s ", vc[i]->name_.c_str());
}
return 0;
}// output: sasaki satchel nozomi qingtian
對(duì)于sort的第三個(gè)函數(shù),用戶可以自己定義任何類型的比較方式,但是需要滿足 strict weak ordering 的條件:
X a; X b; Condition: Test Result a is equivalent to b: Compare(a, b) false Compare(b, a) false a is less than b Compare(a, b) true Compare(b, a) false b is less than a Compare(a, b) false Compare(b, a) true
上述例子中的 Compare 函數(shù)基于 Character 對(duì)象的 age_ 變量值進(jìn)行比較。根據(jù) strict weak ordering 的條件,對(duì) vector 按照某種條件進(jìn)行排序就比較好理解了。
對(duì)于 vector 的兩個(gè)元素 a, b,如果 a 必須排在 b 前面,需要滿足下面的條件:Compare(a, b) = true, Compare(b, a) = false; 如果滿足 Compare(a, b) = false & Compare(b, a) = false,則說(shuō)明兩個(gè)元素是相等的;
拓展:對(duì) vector 中的元素進(jìn)行排序,使得 age_ 為 1 的元素排在前面,age_ != 1的元素排在后面;
分析:這種情況下 Character 被分為兩類,age_ ==1 和 age_ != 1;對(duì)于任意兩個(gè) Character 對(duì)象 a, b:
1. 相等(a == b):a->age_ == 1 && b->age_ ==1,或者 a->age_ != 1 && b->age_ != 1;
2. 小于(a < b):a->age_ == 1 && b->age_ != 1;
class Compare {
public:
bool operator() (Character* ca, Character* cb) {
if (ca->age_ == 1 && cb->age_ == 1 ||
ca->age_ != 1 && cb->age_ != 1) return false;
return ca->age_ == 1;
}
};
完整的測(cè)試代碼:
class Character {
public:
Character(int n, string s) : age_(n), name_(s) {}
int age_;
string name_;
};
class Compare {
public:
bool operator() (Character* ca, Character* cb) {
if (ca->age_ == 1 && cb->age_ == 1 ||
ca->age_ != 1 && cb->age_ != 1) return false;
return ca->age_ == 1;
}
};
int main() {
vector<Character*> vc{ new Character(1, "sasaki"), new Character(2, "nozomi"), new Character(1, "satchel"), new Character(6, "qingtian") };
sort(vc.begin(), vc.end(), Compare());
for (int i = 0; i < vc.size(); ++i) {
printf("%s ", vc[i]->name_.c_str());
}
return 0;
}// output: sasaki satchel nozomi qingtian
Reference:
1. std::sort
2. comparator
3. strict weak order
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
C語(yǔ)言修煉之路一朝函數(shù)思習(xí)得?模塊思維世間生下篇
函數(shù)是一組一起執(zhí)行一個(gè)任務(wù)的語(yǔ)句。每個(gè)?C?程序都至少有一個(gè)函數(shù),即主函數(shù)?main()?,所有簡(jiǎn)單的程序都可以定義其他額外的函數(shù)2022-03-03
VSstudio中scanf返回值被忽略的原因及解決方法(推薦)
這篇文章主要介紹了VSstudio中scanf返回值被忽略的原因及其解決方法,scanf返回值被忽略,接下來(lái)我就告訴大家該如何解決這個(gè)問(wèn)題,需要的朋友可以參考下2022-09-09
C++使用Kruskal和Prim算法實(shí)現(xiàn)最小生成樹
這篇文章主要介紹了C++使用Kruskal和Prim算法實(shí)現(xiàn)最小生成樹,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C語(yǔ)言中system()函數(shù)的用法總結(jié)
system()函數(shù)功能強(qiáng)大。以下小編就為大家介紹一下在C語(yǔ)言中system()函數(shù)的用法。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-10-10
C++實(shí)現(xiàn)查找二叉樹中和為某一值的所有路徑的示例
這篇文章主要介紹了C++實(shí)現(xiàn)查找二叉樹中和為某一值的所有路徑的示例,文中的方法是根據(jù)數(shù)組生成二叉排序樹并進(jìn)行遍歷,需要的朋友可以參考下2016-02-02
c++統(tǒng)計(jì)文件中字符個(gè)數(shù)代碼匯總
本文給大家匯總介紹了3種使用C++實(shí)現(xiàn)統(tǒng)計(jì)文件中的字符個(gè)數(shù)的方法,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。2015-09-09
C++俄羅斯方塊游戲 無(wú)需圖形庫(kù)的俄羅斯方塊
這篇文章主要為大家詳細(xì)介紹了無(wú)需圖形庫(kù)的C++俄羅斯方塊游戲,重溫經(jīng)典游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06
使用設(shè)計(jì)模式中的單例模式來(lái)實(shí)現(xiàn)C++的boost庫(kù)
這篇文章主要介紹了使用設(shè)計(jì)模式中的單例模式來(lái)實(shí)現(xiàn)C++的boost庫(kù)的方法,其中作者對(duì)線程安全格外強(qiáng)調(diào),需要的朋友可以參考下2016-03-03

