sort對類物件進行排序

2021-08-19 16:34:42 字數 4016 閱讀 3971

c++程式設計中常需要對物件進行排序,有可能還要根據物件中的多個成員的值進行排序,c++中提供了sort泛型演算法便於利用。

需要注意的是,sort排序函式不是穩定的,穩定的排序可以用table_sort。穩定是指函式可保證相等元素的原本相對次序在排序後保持不變。

template void sort (randomaccessiterator first, randomaccessiterator last);  

template void sort (randomaccessiterator first, randomaccessiterator last, compare comp);

第乙個函式有兩個引數,分別是隨機訪問迭代器first和last,它預設使用迭代器引用的operator《進行排序。第二個函式有三個引數,前兩個和第乙個一樣,第三個引數是乙個compare,也就是說它使用comp對迭代器引用的物件進行排序。comp是乙個二元函式,它接受前兩個引數指定範圍內的兩個元素,它的返回值可以轉換為bool型別,這個函式不改變迭代器引用的物件,而且,它可以是函式指標和函式物件。

下面舉乙個例子

#include #include #include using namespace std;

int main()

; sort(ivec.begin(), ivec.end());

for (auto &m : ivec)

cout << m << endl;

return 0;

}

可以利用一下四種方法來對物件進行排序

struct test  

bool operator<(const test &t) const

};

bool operator<(const test &t1, const test &t2)

在比較時直接利用

sort(ivec.begin(), ivec.end());
上面寫了兩種過載方式:成員函式或者非成員函式,不可兩個都用,一種即可。

若有兩個成員依次比較則可以這樣

struct test 

bool operator<(const test &t) const

};

struct test 

};bool mycomp(const test &t1, const test &t2)

呼叫時

sort(ivec.begin(), ivec.end(), mycomp);
對物件的對個成員比較時,對mycomp進行改寫

函式物件是定義了函式呼叫操作符()的類的物件。

struct test 

};class mycomp

};

呼叫時

sort(ivec.begin(), ivec.end(), mycomp());
這裡定義了乙個類mycomp,它定義了operator(),因此cmp的物件就是函式物件,它的物件可以當作函式一樣使用。在mycomp的operator()中,有兩個test類型別的引數,它們進行比較得到布林值。在呼叫時第三個引數用的是預設建構函式構造的乙個mycomp臨時物件。

在中定義了多種模板,其中二元函式模板如下:

template struct binary_function ;
它只定義了三個引數,分別是二元函式的兩個運算元和返回值。在使用中我們需要對上面的類進行派生,新增operator(),然後就可以使用函式物件了

。看一下less的實現:

template struct less : binary_function   

};

使用時呼叫、

sort(ivec.begin(), ivec.end(), less());
實現自己的mycomp

class mycomp : public binary_function  

};

呼叫方式

sort(ivec.begin(), ivec.end(), mycomp());
map是stl裡面的乙個模板類,現在我們來看下map的定義:

template < class key, class t, class compare = less,  

class allocator = allocator> > class map;

它有四個引數,其中我們比較熟悉的有兩個: key 和 value。第四個是 allocator,用來定義儲存分配模型的,此處我們不作介紹。

現在我們重點看下第三個引數: class compare = less,這也是乙個class型別的,而且提供了預設值 less。

在我們插入鍵值對時,就會按照key的大小順序進行儲存。這也是作為key的型別必須能夠進行《運算比較的原因。

例子:map裡面儲存,若按string 從大到小排序

map>
自己定義乙個按string的長度排序

struct cmpbykeylength   

};

呼叫

map
上面都是對key進行排序,如何對value進行排序?

首先想到的是利用stl中提供的sort演算法實現,這個想法是好的,不幸的是,sort演算法有個限制,利用sort演算法只能對序列容器進行排序,就是線性的(如vector,list,deque)。map也是乙個集合容器,它裡面儲存的元素是pair,但是它不是線性儲存的(map內部本身就是按序儲存的(比如紅黑樹)),所以利用sort不能直接和map結合進行排序。

雖然不能直接用sort對map進行排序,那麼我們可不可以迂迴一下,把map中的元素放到序列容器(如vector)中,然後再對這些元素進行排序。

元素型別為pair,具體定義如下:

template struct pair  

pair(const t1& x, const t2& y) : first(x), second(y) {}

template pair (const pair&p) : first(p.first), second(p.second)

}

pair也是乙個模板類,這樣就實現了良好的通用性。它僅有兩個資料成員first 和 second,即 key 和 value,而且

在標頭檔案中,還為pair過載了 < 運算子, 具體實現如下:

templateinline bool  

operator<(const pair<_t1, _t2>& __x, const pair<_t1, _t2>& __y)

排序方式是先按first小的進行排序,若first相等則按second小進行排序

既然pair已經過載了《符,而且我們不能修改其實現,又不能在外部重複實現過載《符。

那麼我們如何實現對pair按value進行比較呢? 第一種:是最原始的方法,寫乙個比較函式;  第二種:剛才用到了,寫乙個函式物件。這兩種方式實現起來都比較簡單。

typedef pairpair;  

bool cmp_by_value(const pair& lhs, const pair& rhs)

struct cmpbyvalue

};

呼叫

vectorivec;

......

sort(ivec.begin(),ivec.end(), cmpbyvalue());//或者sort(ivec.begin(),ivec.end(), cmp_by_value);

利用sort對結構體進行排序

我定義了乙個學生型別的結構體來演示sort排序對結構體排序的用法 具體用法看 include include include sort函式包含的標頭檔案 using namespace std 定義乙個學生型別的結構體 typedef struct student student 這是函式是sort...

對List物件進行排序

最近遇到需要對 list 物件按照某一引數 string型別 進行排序的問題,網上教的大多是自己寫排序方法或者用collections.sort 方法按照某一int型引數進行排序,找了好久找到一種很方便快捷的排序方法。對systemdatelist按systemtype進行排序 systemdate...

sort 進行下標排序

在多個資料關聯,需要進行排序又不想寫結構體怎麼辦。一種很好的方法就是進行陣列的下表排序。這裡給出直接用庫函式sort的下標排序。用sort對下標進行排序 include include using namespace std int a 8 int cmp int x,int y 排序是依據a陣列進...