Hoare划分严格或不严格不等式
Hoare partitioning strict or not strict inequalities?
我很难实现霍尔的分区算法。基本上,我想做的是将数组分为两部分,第一部分包含小于给定x
的数字,另一部分包含更大的数字。然而,我就是想不出一个好的实现。这是我的代码:
void hoare(vector<int>&arr,int end, int pivot)
{
int i = 0;
int j = end;
while (i < j)
{
while (arr[i] < pivot)
i += 1;
while (arr[j] > pivot)
j -= 1;
swap(arr[i],arr[j]);
}
// return arr;
for (int i=0; i<end; i++)
printf("%d ", arr[i]);
}
现在我发现很多网站都有(arr[i] <= pivot)
,而不是我放在那里的。然而,当我这样做的时候,对于这样的数组:
1 3 5 7 9 2 4 6 8
我得到:
1 3 5 4 9 2 7 6 8
但话说回来,在我的版本中,对于这样一组:
12 78 4 55 4 3 12 1 0
程序冻结,因为外循环中的两个条件都不满足,所以它只是一遍又一遍地执行,而不递增j
或i
。
枢轴是指向数组中特定数字的指针,从1开始计数;例如,在第一个例子中,传递给函数的数字3意味着pivot
等于arr[2]
,即5
如果这是一个棘手的问题或已经得到回答,我很抱歉,但我花了一整天的时间(也在网上搜索解决方案(都无济于事,现在我有了自杀的想法。
提前谢谢。
分割序列的简单答案当然是使用
auto it = std::partition(vec.begin(), vec.end(),
std::bind2nd(std::less<int>(), pivot));
函数并不真正关心谓词,而是将序列重新排列为两个序列:一个是谓词生成true
,另一个是断言生成false
。该算法在第一个子序列(由谓词为true
的元素组成(的末尾返回迭代器。有趣的是,该算法应该在前向迭代器上工作(不过,如果它真的有前向迭代器,它可以使用相当多的交换(。您正在实现的算法显然需要双向迭代器,也就是说,我将忽略同样适用于前向序列的要求。
在实现算法时,我会遵循完全相同的接口,因为迭代器抽象对序列算法非常有效。算法本身简单地使用std::find_if()
来查找范围[begin, end)
中的迭代器it
,使得谓词不成立:
it = std::find_if(begin, end, not1(pred));
如果存在这样的迭代器,则使用std::find_if()
在[std::reverse_iterator<It>(end), std::reverse_iterator<It>(it))
中搜索迭代器rit
,使得谓词保持:
rit = std::find_if(std::reverse_iterator<It>(end), std::reverse_iterator<It>(it),
pred);
如果存在这样的迭代器,则它std::swap()
会相应地更新begin
和end
:
std::swap(*it, *rit);
begin = ++it;
end = (++rit).base();
如果未找到it
或rit
,则算法终止。将这个逻辑放入一个一致的算法中似乎是相当直接的。请注意,该算法甚至不能使用您尝试使用的运算符,即概念上只能比较x < pivot
和x >= pivot
(与!(x < privot)
相同(的元素。
下面的实现没有经过测试,但完整的算法看起来像这样:
template <typename BiIt, typename Pred>
BiIt partition(BiIt it, BiIt end, Pred pred) {
typedef std::reverse_iterator<BiIt> RIt;
for (RIt rit(end);
(it = std::find_if(it, end, std::not1(pred))) != end
&& (rit = std::find_if(RIt(end), RIt(it), pred)) != RIt(it);
++it, end = (++rit).base()) {
std::swap(*it, *rit);
}
return it;
}
- 查找不等式为真的次数时出现问题
- C++中 c_str() 和字符* 的不等式
- 查找满足浮点不等式方程的最小整数
- 为什么以下不等式在C++计算为真?
- QuickSort中使用的Hoare分区代码(Ref Cormen Book)陷入无限循环
- 奇怪的不等式 - WC_BUTTONW不等于 L "Button" ?
- 不等式比较结果 移至 C++11 时未使用的警告
- 检查是否满足任意不等式的列表
- 多维std::valarray和不等式
- 模板类中的不等式检查
- Python,C++,C#,F#中的不合逻辑的不等式
- lambdas和等式/不等式算子
- std::字符串不等式实现的std::集
- 为什么在很多c++标准库代码中将不等式测试为(!(a==b)) ?
- Hoare分区代码不起作用
- 伪浮点不等式由于编译器优化
- 根据模板参数不等式执行不同的函数
- Hoare划分严格或不严格不等式