我有以下分区方法和kthsmallest方法(快速排序的变化),它适用于某些情况,但在某些情况下为我提供值32767。使用快速排序的第k个最小数字
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)...我知道这对你的问题没有帮助 –
我认为' k> 0&k <= high-low + 1'是一个拼写错误,你打算'&&'?另外,这个快速选择例程从哪里来?这是你从头开始发明的吗?我问,因为它看起来像你需要把它带回绘图板。记住,你不需要排序,但只需要识别包含第k个元素的分区。我怀疑没有进一步的评论或回答是由于很多头脑搔痒试图理清你正在努力完成的事情。请发布[** Minimal,Complete,and Verifiable example **](http://stackoverflow.com/help/mcve) –
@ DavidC.Rankin QuickSelect?我没有提到问题中的任何地方。如果你的意思是快速排序,那么我已经在问题本身中指定了这是快速排序算法的变体。是的,我不需要排序,这就是分区基于'k'的原因。 – Karan