个人认为掌握并灵活的使用stl的算法,对我们c++编程有着事半功倍的效果,排序算法的使用和掌握更加重要。
使用的最多的算法可能就是sort了,或者qsort(条款46的存在可能会让更多人倾向于使用sort而不是qsort)。例如有一个Widget的Vector,你需要挑选出Widget质量最好5个,剩下的可以保持无序。
这时候我们不需要完全排序,sort显得有些浪费。
而partail_sort可以胜任这个目标:
struct Widget
{
Widget(int value) :m_value(value) {}
int m_value;
};
vector vec =
{ Widget(0),
Widget(11),
Widget(12),
Widget(3),
Widget(8),
Widget(6),
Widget(2),
Widget(1),
Widget(8),
Widget(7),
Widget(10),
Widget(9)
};
std::partial_sort(vec.begin(), vec.begin() +5, vec.end(), [](const Widget& lhs, const Widget& rhs)
{
return rhs.m_value < lhs.m_value;
});
for (auto v : vec)
{
cout << " element : "<
按照文档的解释应该是不关心顺序的得到质量较好的Widget,而partail_sort则关心这个顺序(实际上在我的测试中nth_element也都是排序的状态,不知是否是我理解错误,希望有人可以指出!!!)
图片来自于原书
稳定的含义就是例如:未排序的时候A在B之前并且两者质量相同,在排序之后A依旧会在B之前,而partail_sort、nth_element不关心这个顺序。
std::nth_element(vec.begin(), vec.begin() + vec.size() / 2, vec.end(), [](const Widget& lhs, const Widget& rhs)
{
return rhs.m_value < lhs.m_value;
});
cout << " min value : " << vec[vec.size() / 2].m_value << endl;
std::nth_element(vec.begin(), vec.begin() + vec.size() * 0.25, vec.end(), [](const Widget& lhs, const Widget& rhs)
{
return rhs.m_value < lhs.m_value;
});
cout << " 75% value : " << vec[vec.size() * 0.25].m_value << endl;
std::nth_element(vec.begin(), vec.begin() + 1, vec.end(), [](const Widget& lhs, const Widget& rhs)
{
return rhs.m_value < lhs.m_value;
});
cout << " second value : " << vec[1].m_value << endl;
有时候你需要质量等级为10级以上的Widget,而其他的属于不合格的。如果使用sort等,你需要排序并找到第一个不符合要求的位置,这样略嫌麻烦。而partition实现的功能就是分开符合某一标准的元素都在区间开头。
auto iterGoodEnd = std::partition(vec.begin(), vec.end(), [=](const Widget& item)
{
return item.m_value > 10;
});
auto iterBegin = vec.begin();
while (iterBegin != iterGoodEnd)
{
cout << (*iterBegin).m_value << endl;
++iterBegin;
}
另外性能很可能也是我们关注的一点,按照需要更少的资源(时间、空间)排序: