【发布时间】:2013-08-23 09:28:47
【问题描述】:
假设我们有一个:
class Widget;
std::vector<Widget>;
我们有一个函数:
bool belongsToLeft(Widget w);
我想根据这个谓词对容器进行排序。到目前为止,我认为这个算法。它从范围的两端进行。一旦它找到一对同时属于另一端的值,它就会交换它们。
template <typename TIterator, typename TPredicate>
TIterator separate(TIterator begin, TIterator end, TPredicate belongsLeft)
{
while (true)
{
while (begin != end && belongsLeft(*begin))
++begin;
while (begin != end && !belongsLeft(*end))
--end;
if (begin == end)
return begin;
std::swap(*begin, *end);
}
}
问题是这个算法不稳定:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> numbers = {6, 5, 4, 3, 2, 1};
separate(numbers.begin(), numbers.end(), [](int x){return x%2 == 0;});
for (int x : numbers)
std::cout << x << std::endl;
return 0;
}
输出:
6
2
4
3
5
1
如何修改此算法以使其稳定并保持线性时间?
【问题讨论】:
-
你为什么不用
std::stable_sort()? -
我想利用只有两个可能值的事实,以便算法在线性时间内运行。
-
只有在
*end > *begin不能保证的情况下才能进行交换;将谓词放在开始/结束上。 -
您认为示例中的输出到底有什么问题?
-
@Steven 我想要一个稳定的排序。也就是说,数字应该以与输入相同的相对顺序出现:6、4、2、5、3、1
标签: c++ algorithm c++11 vector stl