STL容器的排序


STL容器的排序,支持隨機訪問的容器vector,deque,string沒有sort成員,可調用std::sort排序;list排序調用自帶的list::sort。

下面是std::sort函數,有兩個版本:

 

[cpp]  view plain  copy
 
  1. template <class RandomAccessIterator>  
  2. void sort ( RandomAccessIterator first, RandomAccessIterator last );  
  3.   
  4. template <class RandomAccessIterator, class Compare>  
  5. 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(大於等於)

當容器元素為內建類型時可以使用,注意使用的格式,要加模版參數(由於是模板類)和后面的(),如下:

[cpp]  view plain  copy
 
  1. sort(vec.begin(), vec.end(), less<int>());  

對於復合類型,實現排序方式有3種方法:
1) 重載operator<操作符
2) 寫全局的比較函數
3) 寫仿函數,重載operator()形式為:bool operator()(const 類名& 參數){…}

下面看看這3種方法的實現:

 

 

[cpp]  view plain  copy
 
  1. // 排序元素,比較的對象  
  2. struct Person  
  3. {  
  4.   Person(int id, const string& name, int age): id_(id), name_(name), age_(age)  
  5.   {}  
  6.     
  7.   int id_;  
  8.   string name_;  
  9.   int age_;  
  10. };  
[cpp]  view plain  copy
 
  1. // 方式1:重載operator<用於排序時的比較(寫在函數體內)  
  2. bool operator< (const Person& rt)  
  3. {  
  4.   return this->id_ < rt.id_;  
  5. }  
  6.   
  7. // 排序函數寫法,默認調用operator<  
  8. sort(members.begin(), members.end());  
[cpp]  view plain  copy
 
  1. // 方式2:寫比較函數  
  2. bool CompAge(const Person& pl, const Person& pr)  
  3. {  
  4.   return pl.age_ < pr.age_;  
  5. }  
  6.   
  7. // 排序時傳入比較函數指針  
  8. sort(members.begin(), members.end(), CompAge);  
[cpp]  view plain  copy
 
  1. // 方式3:仿函數  
  2. struct CompName  
  3. {  
  4.   bool operator()(const Person& pl, const Person& pr)  
  5.   {  
  6.     return pl.name_ < pr.name_;  
  7.   }  
  8. };  
  9.   
  10. // 排序時傳入函數對象  
  11. sort(members.begin(), members.end(), CompName());  

用函數對象代替函數指針的優點:
1. 函數對象可以存儲中間結果在數據成員中,而函數想要存中間結果須要設全局變量或靜態變量,這個是我們不想要的。
2. 在函數對象中編譯器可以實現內聯調用,從而提升性能。

 

下面看一個函數對象的擴展應用

 

[cpp]  view plain  copy
 
  1. // 利用函數對象實現升降排序  
  2. struct CompNameEx{  
  3.   CompNameEx(bool asce) : asce_(asce)  
  4.   {}  
  5.   bool operator()(const Person& pl, const Person& pr)  
  6.   {  
  7.     return asce_ ? pl.name_ < pr.name_ : pr.name_ < pl.name_;<span style="white-space:pre">   </span>// 《Eff STL》條款21: 永遠讓比較函數對相等的值返回false  
  8.   }  
  9. private:  
  10.   bool asce_;  
  11. };  
  12. // 使用仿函數排序(升降序)  
  13. sort(members.begin(), members.end(), CompNameEx(false));  
 

注意:如果是指針的容器,比較函數的參數也應是指針。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM