我正在尝试从我的教科书中提供的伪代码“翻译”此算法。我的程序一直在崩溃,我不确定我的实现在哪里出错了。这是图像中的伪代码,我的代码位于其下方:
int kSmallFirst (int k, int anArray[], int first, int last) {
int pivotIndex = 0;
if (k < pivotIndex - first + 1)
return kSmallFirst(k, anArray, first, pivotIndex - 1);
else if (k == pivotIndex - first + 1)
return pivotIndex;
else
return kSmallFirst(k - (pivotIndex - first + 1), anArray, pivotIndex + 1, last);
}
int main () {
int i = 0;
int arr[512];
fstream data;
data.open("data.txt");
while (!data.eof()) {
data >> arr[i];
i++;
}
data.close();
cout << kSmallFirst(42, arr, 0, i-1);
return 0;
}
非常感谢!
答案 0 :(得分:4)
问题是:您没有实现算法的主要部分,这在您的书中用 italic 字体描述:
选择一个透视值“p”形式'anArray [first..last]'
将'anArray [first..last]'的值分为'p'
这两行不是评论!它们是伪代码,您将转换为C / C ++ ,以使您的代码能够执行您希望它执行的操作。
答案 1 :(得分:2)
请注意,kSmallFirst
从不使用anArray
,因此与JoriO所说的相反,这不是输入问题。即使尝试使用范围main
,也会将范围[0 .. -1]作为kSmallFirst
的{{1}}和first
传递。
您需要了解算法正在做什么,否则CiaPan提到您将无法实现最重要的部分。
last
是:
kSmall
和anArray
first
分区
last
和pivotIndex
anArray
分区中选择first
last
的元素移到anArray[pivotIndex]
以下且所有大于pivotIndex
的元素移到anArray[pivotIndex]
以上pivotIndex
的下一对分区,从anArray
到first
的分区以及从pivotIndex
到pivotIndex
的分区last
将对包含kSmall
元素的范围进行递归考虑到这一点,重写k
将产生:
kSmall
我相信你会注意到if语句中的数学与书不同。我选择使用#include <algorithm>
#include <functional>
int kSmall(int k, int* anArray, int first, int last){
int p = anArray[(last - first) / 2 + first]; // Choose a pivot value from anArray[first .. last]
int* pivotIndex = std::partition(anArray + first, anArray + last, std::bind2nd(std::less<int>(), p)); // Partition the values of anArray around p
if(k < pivotIndex - anArray){
return kSmall(k, anArray, first, pivotIndex - anArray);
}
else if(k == pivotIndex - anArray){
return pivotIndex - anArray;
}
else{
return kSmall(k, anArray, pivotIndex - anArray, last);
}
}
参数来实现kSmall
,本书选择使用int
参数。
答案 2 :(得分:0)
您选择枢轴索引值是错误的。
由于这是递归,因此您需要为每次调用更新数据透视。
让它更通用。
在 kSmallFirst函数中,
使用 pivotIndex = first ,而不是 pivotIndex = 0 。