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