一:使用sort必须了解的事情:
-
必须的头文件#include < algorithm>和using namespace std;
-
它是属于c++ STL vector中的方法;
-
它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n);
-
Sort函数有三个参数:(第三个参数可不写)
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
二:详细讲解sort的第三个参数
第三个参数有三种方式表示:(1)重载运算符(2)全局的比较函数(3)函数对象。它们本质上都是返回bool类型(这里划重点,都必须有返回值,而且返回值是bool类型),提供给sort函数作为第三个参数。
下面我们一个个的举例子看:
下文的所有例子都来自于:https://blog.csdn.net/aastoneaa/article/details/8471722
我这里当一波代码搬运工
(1)重载运算符
首先得明确,重载运算符,重载谁的运算符啊?当然是你需要进行排序的结构体或者类的运算符鸭。因此这种方法会改变原有的结构体或者类。
下面到了代码搬运的时间了
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct TItem
{
int m_i32Type;
int m_i32ID;
bool operator <(const TItem& rhs) const // 升序排序时必须写的函数
{
return m_i32Type < rhs.m_i32Type;
}
bool operator >(const TItem& rhs) const // 降序排序时必须写的函数
{
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()); 默认情况为升序
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;
}
个人感觉这种方法好麻烦啊~~~
(2)全局比较函数
这种方式是直接写一个写一个全局的函数即可,废话不多说,上代码
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct TItem
{
int m_i32Type;
int m_i32ID;
};
//升序排列需要的全局函数
bool lessmark(const TItem& stItem1, const TItem& stItem2)
{
return stItem1.m_i32Type < stItem2.m_i32Type;
}
//降序排列需要的全局函数
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)函数对象
这个意思就是,我创建一个类,然后在这个类里面重载他的()运算符。上代码“
#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;
}
/*
结果如下:
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的稳定的。
*/
其实还有第四种:其他骚里骚气的方法-----lambda 表达式
来来让我们看看什么是Lambda表达式
来自:https://msdn.microsoft.com/zh-cn/library/dd293608.aspx
在 C++ 11 中,lambda 表达式(通常称为 "lambda")是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象的简便方法。 Lambda 通常用于封装传递给算法或异步方法的少量代码行。
这里简单理解:(1)少量(2)是一种函数(3)当作参数传递
再次搬运一个列子
#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这东西.....自己体会吧,可以参考本小节的链接。
三: 结语
- 示例代码中只有>和<关系处理,==关系是如何推导出来的?
这个我也不知道,但是在使用运算符重载的时候,尽量重载==符号
//重载==
bool operator==( const MYSTRUCT& objstruct) const
{
return objstruct.id==id;
}
- 在上面的例子中,vector中存放的都是结构(对象)本身,如果存放的是结构指针,该如何排序呢?
此时只能通过全局的比较函数或者函数对象来做,且比较函数的参数要是指针类型的。
网友评论