一:使用sort必須了解的事情:
必須的頭文件#include < algorithm>和using namespace std;
它是屬于c++ STL vector中的方法;
它使用的排序方法是類(lèi)似于快排的方法,時(shí)間復(fù)雜度為n*log2(n)诗箍;
Sort函數(shù)有三個(gè)參數(shù):(第三個(gè)參數(shù)可不寫(xiě))
(1)第一個(gè)是要排序的數(shù)組的起始地址蹲姐。
(2)第二個(gè)是結(jié)束的地址(最后一位要排序的地址)
(3)第三個(gè)參數(shù)是排序的方法丹泉,可以是從大到小也可是從小到大仅淑,還可以不寫(xiě)第三個(gè)參數(shù)屏箍,此時(shí)默認(rèn)的排序方法是從小到大排序绘梦。
二:詳細(xì)講解sort的第三個(gè)參數(shù)
第三個(gè)參數(shù)有三種方式表示:(1)重載運(yùn)算符(2)全局的比較函數(shù)(3)函數(shù)對(duì)象橘忱。它們本質(zhì)上都是返回bool類(lèi)型(這里劃重點(diǎn),都必須有返回值卸奉,而且返回值是bool類(lèi)型)钝诚,提供給sort函數(shù)作為第三個(gè)參數(shù)。
下面我們一個(gè)個(gè)的舉例子看:
下文的所有例子都來(lái)自于:https://blog.csdn.net/aastoneaa/article/details/8471722
我這里當(dāng)一波代碼搬運(yùn)工
(1)重載運(yùn)算符
首先得明確榄棵,重載運(yùn)算符凝颇,重載誰(shuí)的運(yùn)算符啊疹鳄?當(dāng)然是你需要進(jìn)行排序的結(jié)構(gòu)體或者類(lèi)的運(yùn)算符鴨拧略。因此這種方法會(huì)改變?cè)械慕Y(jié)構(gòu)體或者類(lèi)。
下面到了代碼搬運(yùn)的時(shí)間了
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct TItem
{
int m_i32Type;
int m_i32ID;
bool operator <(const TItem& rhs) const // 升序排序時(shí)必須寫(xiě)的函數(shù)
{
return m_i32Type < rhs.m_i32Type;
}
bool operator >(const TItem& rhs) const // 降序排序時(shí)必須寫(xiě)的函數(shù)
{
return m_i32Type > rhs.m_i32Type;
}
};
int main()
{
vector<TItem> stItemVec;
TItem stItem1;
stItem1.m_i32Type = 1;
stItem1.m_i32ID = 1;
TItem stItem2;
stItem2.m_i32Type = 2;
stItem2.m_i32ID = 2;
TItem stItem3;
stItem3.m_i32Type = 3;
stItem3.m_i32ID = 3;
TItem stItem4;
stItem4.m_i32Type = 2;
stItem4.m_i32ID = 4;
stItemVec.push_back(stItem1);
stItemVec.push_back(stItem2);
stItemVec.push_back(stItem3);
stItemVec.push_back(stItem4);
// 升序排序
sort(stItemVec.begin(), stItemVec.end(), less<TItem>());
// 或者sort(ctn.begin(), ctn.end()); 默認(rèn)情況為升序
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
printf("--\n");
// 降序排序
sort(stItemVec.begin(), stItemVec.end(), greater<TItem>());
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
return 0;
}
個(gè)人感覺(jué)這種方法好麻煩啊~~~
(2)全局比較函數(shù)
這種方式是直接寫(xiě)一個(gè)寫(xiě)一個(gè)全局的函數(shù)即可瘪弓,廢話(huà)不多說(shuō)垫蛆,上代碼
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct TItem
{
int m_i32Type;
int m_i32ID;
};
//升序排列需要的全局函數(shù)
bool lessmark(const TItem& stItem1, const TItem& stItem2)
{
return stItem1.m_i32Type < stItem2.m_i32Type;
}
//降序排列需要的全局函數(shù)
bool greatermark(const TItem& stItem1, const TItem& stItem2)
{
return stItem1.m_i32Type > stItem2.m_i32Type;
}
int main()
{
vector<TItem> stItemVec;
TItem stItem1;
stItem1.m_i32Type = 1;
stItem1.m_i32ID = 1;
TItem stItem2;
stItem2.m_i32Type = 2;
stItem2.m_i32ID = 2;
TItem stItem3;
stItem3.m_i32Type = 3;
stItem3.m_i32ID = 3;
TItem stItem4;
stItem4.m_i32Type = 2;
stItem4.m_i32ID = 4;
stItemVec.push_back(stItem1);
stItemVec.push_back(stItem2);
stItemVec.push_back(stItem3);
stItemVec.push_back(stItem4);
sort(stItemVec.begin(), stItemVec.end(), lessmark); //升序排序
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
printf("--\n");
sort(stItemVec.begin(), stItemVec.end(), greatermark); //降序排序
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
return 0;
}
(3)函數(shù)對(duì)象
這個(gè)意思就是,我創(chuàng)建一個(gè)類(lèi)腺怯,然后在這個(gè)類(lèi)里面重載他的()運(yùn)算符袱饭。上代碼“
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct TItem
{
int m_i32Type;
int m_i32ID;
};
class CompLess
{
public:
bool operator ()(const TItem& stItem1, const TItem& stItem2)
{
return stItem1.m_i32Type < stItem2.m_i32Type;
}
};
class CompGreater
{
public:
bool operator ()(const TItem& stItem1, const TItem& stItem2)
{
return stItem1.m_i32Type > stItem2.m_i32Type;
}
};
int main()
{
vector<TItem> stItemVec;
TItem stItem1;
stItem1.m_i32Type = 1;
stItem1.m_i32ID = 1;
TItem stItem2;
stItem2.m_i32Type = 2;
stItem2.m_i32ID = 2;
TItem stItem3;
stItem3.m_i32Type = 3;
stItem3.m_i32ID = 3;
TItem stItem4;
stItem4.m_i32Type = 2;
stItem4.m_i32ID = 4;
stItemVec.push_back(stItem1);
stItemVec.push_back(stItem2);
stItemVec.push_back(stItem3);
stItemVec.push_back(stItem4);
sort(stItemVec.begin(), stItemVec.end(), CompLess()); //升序排序
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
printf("--\n");
sort(stItemVec.begin(), stItemVec.end(), CompGreater()); //降序排序
for (size_t i = 0; i < stItemVec.size(); i++)
printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
return 0;
}
/*
結(jié)果如下:
type: 1, id: 1
type: 2, id: 2
type: 2, id: 4
type: 3, id: 3
--
type: 3, id: 3
type: 2, id: 2
type: 2, id: 4
type: 1, id: 1
可以看出vector的sort的穩(wěn)定的。
*/
其實(shí)還有第四種:其他騷里騷氣的方法-----lambda 表達(dá)式
來(lái)來(lái)讓我們看看什么是Lambda表達(dá)式
來(lái)自:https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
在 C++ 11 中呛占,lambda 表達(dá)式(通常稱(chēng)為 "lambda")是一種在被調(diào)用的位置或作為參數(shù)傳遞給函數(shù)的位置定義匿名函數(shù)對(duì)象的簡(jiǎn)便方法虑乖。 Lambda 通常用于封裝傳遞給算法或異步方法的少量代碼行。
這里簡(jiǎn)單理解:(1)少量(2)是一種函數(shù)(3)當(dāng)作參數(shù)傳遞
再次搬運(yùn)一個(gè)列子
#include <algorithm>
#include <cmath>
void abssort(float* x, unsigned n) {
std::sort(x, x + n,
// Lambda expression begins
[](float a, float b) {
return (std::abs(a) < std::abs(b));
} // end of lambda expression
);
}
lambda這東西.....自己體會(huì)吧晾虑,可以參考本小節(jié)的鏈接疹味。
三: 結(jié)語(yǔ)
- 示例代碼中只有>和<關(guān)系處理,==關(guān)系是如何推導(dǎo)出來(lái)的帜篇?
這個(gè)我也不知道糙捺,但是在使用運(yùn)算符重載的時(shí)候,盡量重載==符號(hào)
//重載==
bool operator==( const MYSTRUCT& objstruct) const
{
return objstruct.id==id;
}
- 在上面的例子中坠狡,vector中存放的都是結(jié)構(gòu)(對(duì)象)本身继找,如果存放的是結(jié)構(gòu)指針,該如何排序呢逃沿?
此時(shí)只能通過(guò)全局的比較函數(shù)或者函數(shù)對(duì)象來(lái)做,且比較函數(shù)的參數(shù)要是指針類(lèi)型的幻锁。