【发布时间】:2016-08-15 03:12:59
【问题描述】:
我有以下分区方法和 kthsmallest 方法(快速排序的变体),它适用于某些情况,但在少数情况下给我 32767 的值。
void swap(int* a, int* b){
int temp = *b;
*b = *a;
*a = temp;
}
int partition(int* arr, int l, int r){
int pivot = arr[r];
int i = l, j=0;
for(j=l; j<=r-1; j++){
if(arr[j] <= pivot){
swap(&arr[i], &arr[j]);
i++;
}
}
swap(&arr[i], &arr[j]);
return i;
}
而kthsmallest函数如下:-
int kthsmallest(int* arr, int low, int high, int k){
/* low = 0 and high = #elements - 1 */
/* k is in between 1 to high + 1 */
if (k>0 & k<=high-low+1) {
// pos is partitioning index, arr[p] is now at right place
int pos = partition(arr, low, high);
// Separately sort elements before / partition and after partition
if(pos-low == k-1){
return arr[pos];
}
//if position returned is greater than k, recurse left subarray
else if(pos-low > k-1){
return kthsmallest(arr, low, pos-1, k);
}
return kthsmallest(arr, pos+1, high, k-(pos+1));
}
}
但是,当我更改 kthsmallest 函数中的最后一个调用时它会起作用,即
更改:return kthsmallest(arr, pos+1, high, k-(pos+1));
收件人:return kthsmallest(arr, pos+1, high, k-(pos+1)+low);
我想了解为什么我需要将低值添加到 k-(pos+1)。因为在我看来,当我们在右侧有递归进入的子数组时,大数组中的第 k 个最小数字归结为 k - 最后一个分区元素 -1 即 k-(pos+1)。
【问题讨论】:
-
如果 k 很小,你可以只保留一个子缓冲区,你可以在 ~n 时间内收集 k 个元素,其中快速排序总是 O(n log n)...我知道它没有t帮助你的问题
-
我认为
k>0 & k<=high-low+1是一个错字,而您想要&&?另外,这个快速选择例程是从哪里来的?这是你从零开始发明的吗?我问是因为看起来你需要把它带回绘图板上。请记住,您不需要排序,只需要识别包含第 k 个元素的分区。我怀疑缺乏进一步的评论或答案是由于很多人挠头试图弄清楚你想要完成的事情。请发帖Minimal, Complete, and Verifiable example -
@DavidC.Rankin 快速选择?我没有在问题的任何地方引用它。如果您的意思是快速排序,那么我已经在问题本身中指定这是快速排序算法的一种变体。是的,我不需要排序,这就是分区基于“k”的原因。