STL容器的排序,,支持隨機(jī)訪問的容器vector,deque,string沒有sort成員,可調(diào)用std::sort排序,;list排序調(diào)用自帶的list::sort,。
下面是std::sort函數(shù),有兩個版本:
- template <class RandomAccessIterator>
- void sort ( RandomAccessIterator first, RandomAccessIterator last );
-
- template <class RandomAccessIterator, class Compare>
- void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
sort函數(shù)有以下特征:
1. 要求輸入一個范圍[first, last)
2. 隨機(jī)迭代器,,能用此算法的容器是支持隨機(jī)訪問的容器:vector, deque, string,。
3.第一個版本使用operator<進(jìn)行比較,默認(rèn)升序排序,,第二個版本使用comp做比較.
關(guān)于參數(shù)comp,,comp帶兩個同類型的參數(shù),如果第一個參數(shù)排在第二個參數(shù)前面,,返回true,,否則返回false
它可以是函數(shù)指針,也可以是函數(shù)對象,。函數(shù)指針好理解,,何謂函數(shù)對象?
函數(shù)對象(Function Object),,是重載了operator()函數(shù)的類(或結(jié)構(gòu)體)實例化出來的對象,,使用起來像函數(shù),又叫仿函數(shù),。
STL本身提供了幾個比較函數(shù),下面這些都是仿函數(shù):
less(小于)
greater(大于)
equal_to(等于)
not_equal_to(不相等)
less_equal(小于等于)
greater_equal(大于等于)
當(dāng)容器元素為內(nèi)建類型時可以使用,,注意使用的格式,要加模版參數(shù)(由于是模板類)和后面的(),,如下:
- sort(vec.begin(), vec.end(), less<int>());
對于復(fù)合類型,,實現(xiàn)排序方式有3種方法:
1) 重載operator<操作符
2) 寫全局的比較函數(shù)
3) 寫仿函數(shù),重載operator()形式為:bool operator()(const 類名& 參數(shù)){…}
下面看看這3種方法的實現(xiàn):
- // 排序元素,,比較的對象
- struct Person
- {
- Person(int id, const string& name, int age): id_(id), name_(name), age_(age)
- {}
-
- int id_;
- string name_;
- int age_;
- };
- // 方式1:重載operator<用于排序時的比較(寫在函數(shù)體內(nèi))
- bool operator< (const Person& rt)
- {
- return this->id_ < rt.id_;
- }
-
- // 排序函數(shù)寫法,,默認(rèn)調(diào)用operator<
- sort(members.begin(), members.end());
- // 方式2:寫比較函數(shù)
- bool CompAge(const Person& pl, const Person& pr)
- {
- return pl.age_ < pr.age_;
- }
-
- // 排序時傳入比較函數(shù)指針
- sort(members.begin(), members.end(), CompAge);
- // 方式3:仿函數(shù)
- struct CompName
- {
- bool operator()(const Person& pl, const Person& pr)
- {
- return pl.name_ < pr.name_;
- }
- };
-
- // 排序時傳入函數(shù)對象
- sort(members.begin(), members.end(), CompName());
用函數(shù)對象代替函數(shù)指針的優(yōu)點(diǎn):
1. 函數(shù)對象可以存儲中間結(jié)果在數(shù)據(jù)成員中,而函數(shù)想要存中間結(jié)果須要設(shè)全局變量或靜態(tài)變量,,這個是我們不想要的,。
2. 在函數(shù)對象中編譯器可以實現(xiàn)內(nèi)聯(lián)調(diào)用,從而提升性能,。
下面看一個函數(shù)對象的擴(kuò)展應(yīng)用
- // 利用函數(shù)對象實現(xiàn)升降排序
- struct CompNameEx{
- CompNameEx(bool asce) : asce_(asce)
- {}
- bool operator()(const Person& pl, const Person& pr)
- {
- return asce_ ? pl.name_ < pr.name_ : pr.name_ < pl.name_;<span style="white-space:pre"> </span>// 《Eff STL》條款21: 永遠(yuǎn)讓比較函數(shù)對相等的值返回false
- }
- private:
- bool asce_;
- };
- // 使用仿函數(shù)排序(升降序)
- sort(members.begin(), members.end(), CompNameEx(false));
注意:如果是指針的容器,,比較函數(shù)的參數(shù)也應(yīng)是指針。
|