#include #include #include void swp(int i, int j, double xs[]) { double tmp = xs[i]; xs[i] = xs[j]; xs[j] = tmp; } void array_print(double xs[], int n) { printf("["); for (int i = 0; i < n; i++) { printf("%f, ", xs[i]); } printf("]\n"); } int partition(int low, int high, double xs[], int length) { // To understand this function: // - see the note after gt variable definition // - go to commit 578bfa27 and the scratchpad/ folder in it, which has printfs sprinkled throughout int pivot = low + floor((high - low) / 2); double pivot_value = xs[pivot]; swp(pivot, high, xs); int gt = low; /* This pointer will iterate until finding an element which is greater than the pivot. Then it will move elements that are smaller before it--more specifically, it will move elements to its position and then increment. As a result all elements between gt and i will be greater than the pivot. */ for (int i = low; i < high; i++) { if (xs[i] < pivot_value) { swp(gt, i, xs); gt++; } } swp(high, gt, xs); return gt; } double quickselect(int k, double xs[], int length) { int low = 0; int high = length - 1; for (;;) { if (low == high) { return xs[low]; } int pivot = partition(low, high, xs, length); if (pivot == k) { return xs[pivot]; } else if (k < pivot) { high = pivot - 1; } else { low = pivot + 1; } } } int main() { double xs[] = { 2.1, 1.0, 6.0, 4.0, 7.0, -1.0, 2.0, 10.0 }; int length = 8; int k = 2; array_print(xs, 8); double result = quickselect(k, xs, length); printf("The item in pos #%d is: %f\n", k, result); array_print(xs, 8); return 0; }