2023-11-29 20:04:41 +00:00
# include <math.h>
# include <stdio.h>
# include <stdlib.h>
2023-11-29 21:45:42 +00:00
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 ) {
2023-11-29 21:45:42 +00:00
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 ) {
2023-11-29 21:45:42 +00:00
// 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 ] ;
2023-11-29 21:45:42 +00:00
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 ) {
2023-11-29 21:45:42 +00:00
swp ( gt , i , xs ) ;
2023-11-29 21:34:39 +00:00
gt + + ;
}
}
2023-11-29 21:45:42 +00:00
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 ) ;
2023-11-29 21:45:42 +00:00
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 ) ;
2023-11-29 21:45:42 +00:00
array_print ( xs , 8 ) ;
2023-11-29 20:04:41 +00:00
return 0 ;
}