我有以下分區方法和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