squiggle.c/scratchpad/quickselect/quickselect.c

65 lines
1.6 KiB
C
Raw Normal View History

2023-11-29 20:04:41 +00:00
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
void swp(int i, int j, double xs[]){
2023-11-29 21:34:39 +00:00
double tmp = xs[i];
xs[i] = xs[j];
xs[j] = tmp;
}
void array_print(double xs[], int n){
printf("[");
2023-11-29 21:34:39 +00:00
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);
2023-11-29 21:34:39 +00:00
double pivot_value = xs[pivot];
swp(pivot, high, xs);
2023-11-29 21:34:39 +00:00
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);
2023-11-29 21:34:39 +00:00
gt++;
}
}
swp(high, gt, xs);
2023-11-29 21:34:39 +00:00
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;
}
}
}
2023-11-29 20:04:41 +00:00
int main(){
2023-11-29 21:34:39 +00:00
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);
2023-11-29 21:34:39 +00:00
printf("The item in pos #%d is: %f\n", k, result);
array_print(xs, 8);
2023-11-29 20:04:41 +00:00
return 0;
}