STL中排序函數的用法(Qsort,Sort,Stable_sort,Partial_sort,List::sort)

都知道排序很重要,也學了各式各樣的排序算法,冒泡、插入、歸併等等,但其實在ACM比賽中,只要不是太慢的算法,均可以適用(除非某些題目卡時間卡的很死),這個時候,速度與技巧便成了關鍵,而在C++的標準庫中,就已經定義好了一些排序函數,下面來一一介紹它們吧=7=node

Qsort

函數原型爲void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));包含四個參數,分別是待排序數組首地址、數組中待排序元素數量、各元素的佔用空間大小、指向函數的指針(就是本身的排序函數),這個函數在C語言中就可使用了,能夠不包含第四個參數進行對數組的排序,此時系統會自動按照從小到大的排序,例如:算法

int a[] = {4,1,2,3,5,7,6};
qsort(a,7,sizeof(a[0]));

//結果:1 2 3 4 5 6 7

好,那麼qsort如何對結構體進行排序呢,咱們知道,對結構體數組的排序須要本身寫一個排序函數,可是和其餘函數不同的是,qsort的排序函數有其固定的形式,例如:spring

struct node{
    int id,num;
}a[6] = {{1,3},{2,4},{3,1},{4,2},{5,6},{6,5}};

int cmp(const void *a,const void *b){
    node *aa = (node *)a;
    node *bb = (node *)b;
    if(aa->num == bb->num){
        return aa->id < bb->id;
    }
    return aa->num > bb->num;    //按num值升序排序
}

qsort(a,6,sizeof(a[0]),cmp);

能夠看到,cmp函數形參不能直接定義爲相應類型,只能定義爲const void *p 類型,而後強制轉換爲相應類型再作出處理。真是由於如此,咱們在ACM中不會太常常也不建議用qsort函數,但仍是得明白一下操做。數組

 

Sort

這個函數相信你們都很熟悉了,就是經常使用排序函數,給給定區間內進行排序,時間複雜度爲O(N*logN),參數有三個,分別是首地址、末地址和排序函數,第三個參數省略時按照從小到大排序,例如:函數

1 int a[] = {4,1,2,3,5,6};
2 sort(a,a+6);
3 
4 //排序結果: 1 2 3 4 5 6

稍微難一點的就是對結構體數組進行排序,此時,sort函數就有多種選擇方式了,能夠在結構體內重載操做符,寫比較函數或者仿函數等均可以,例如:spa

 1 struct node{
 2     int id,num;
 3 
 4     //重載比較符
 5     bool operator < (const node &b) const{
 6         if(num == b.num){
 7             return id < b.id;
 8         }
 9         return num > b.num;
10     }
11 }a[6] = {{1,3},{2,4},{3,1},{4,2},{5,6},{6,5}};
12 
13 
14 //編寫比較函數
15 int cmp(node &a,node &b){
16     if(a.num == b.num){
17         return a.id < b.id;
18     }
19     return a.num > b.num;
20 }
21 
22 sort(a,a+6);    //重載比較符
23 sort(a,a+6,cmp);    //編寫比較函數

不使用結構體,使用仿函數就是:指針

 1 //編寫仿函數
 2 class CMP{
 3     public:
 4         CMP(int _id,int _num):id(_id),num(_num){}
 5         int id;
 6         int num;
 7         bool operator < (const node &b) const{
 8             if(num == b.num){
 9                 return id < b.id;
10             }
11             return num > b.num;
12         }
13 };
14 
15 vector<CMP>a;
16 sort(a,a+6);

基本上Sort的操做就是這些了。code

 

Stable_sort

其實你會發現不單單sort有stable_sort,partition也有stable_partition,咱們都知道sort是一個不穩定的排序,但stable_sort就是如字面意思同樣,是一個穩定的sort排序,那麼你可能有疑問,排序後,相同的元素會在一塊兒,穩定不穩定不都是同樣的麼,若是你存在這個疑問的話,那就確定仍是作題力度不夠=7=,你只想到了對元素表面的排序,若是是對元素的某種性質排序呢,例如:blog

1 string s[4] = {"spring","lip","eye","winter"};
2 
3 bool cmp(string a, string b){
4     return a.size() < b.size();
5 }
6 
7 sort(s,s+4,cmp);

對於這段代碼,"lip"和"eye"對於比較函數來講是相等的,因此排序後結果可能lip在eye的前面也可能在eye後面,可是若是這裏使用stable_sort,排序前lip在eye前面,無論排序次數如何,lip必定會排在eye的前面。排序

其餘用法和sort同樣。

 

Partial_sort

和字面意思同樣,部分排序,函數有三個參數,分別是區間要排序的首位置、要排序的末位置以及區間末位置,函數的做用就是把區間內前n個元素排序,其餘元素則依次排在末尾,例如:

int a[] = {6,5,4,3,2,1};
partial_sort(a,a+3,a+6);

//排序結果: 1 2 3 6 5 4

函數其餘用法和sort相同,也就沒什麼好講的=7=

 

List::sort

這個是list容器中專有的排序函數,直接對迭代器操做,使用方式爲:

1 list<int>a;
2 a.sort();

 

那麼所有的排序函數已經講完了,若是在以前你只知道一個sort或者qsort的話,是否是忽然以爲知道了不少新東西呢,其實STL的東西遠不止這些,學好了STL,對於咱們作題真的是有質和速度的雙從提高。

還有就是文中說起的仿函數,這個東西也是STL裏面的一大類,會專門將這個的,嘻嘻。

 


後記:有人和我說nth_element函數的講解,可是nth_element並不算是排序函數,因此沒有寫在這裏,都會寫的=7=

相關文章
相關標籤/搜索