80 lines
3.3 KiB
C
80 lines
3.3 KiB
C
#ifndef ZS_SORT_H
|
|
#define ZS_SORT_H
|
|
|
|
#include <stdint.h>
|
|
#include "qsort.h"
|
|
|
|
/** Always at most log(n) space needing quicksort variant */
|
|
static inline void zssort(uint32_t array[], int low, int high) {
|
|
/* (*) Loop handles original "other half recursion"! */
|
|
while(low < high) {
|
|
int pi = partition(array, low, high);
|
|
|
|
/* If we recurse only the smaller part */
|
|
/* That ensures at most n/2 elements can */
|
|
/* be on any given level of the recursion */
|
|
/* tree: that is we ensure log2(N) memuse! */
|
|
if((pi - low) < (high - pi)) {
|
|
// Left smaller: recurse left of pivot
|
|
zssort(array, low, pi - 1);
|
|
// (*) Update partitioning loop for remaining part
|
|
low = pi + 1;
|
|
} else {
|
|
// Right smaller: recurse right of pivot
|
|
zssort(array, pi + 1, high);
|
|
// (*) Update partitioning loop for remaining part
|
|
high = pi - 1; /* high inclusive! */
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Always at most log(n) space needing randomized quicksort variant */
|
|
static inline void zssort_rand(uint32_t array[], int low, int high, rpivotstate *state) {
|
|
while (low < high) {
|
|
int pi = pick_pivot(state, (high + 1) - low) + low;
|
|
|
|
pi = partition_with_pivot(array, pi, low, high);
|
|
/* If we recurse only the smaller part */
|
|
/* That ensures at most n/2 elements can */
|
|
/* be on any given level of the recursion */
|
|
/* tree: that is we ensure log2(N) memuse! */
|
|
if((pi - low) < (high - pi)) {
|
|
// Left smaller: recurse left of pivot
|
|
zssort_rand(array, low, pi - 1, state);
|
|
// (*) Update partitioning loop for remaining part
|
|
low = pi + 1;
|
|
} else {
|
|
// Right smaller: recurse right of pivot
|
|
zssort_rand(array, pi + 1, high, state);
|
|
// (*) Update partitioning loop for remaining part
|
|
high = pi - 1; /* high inclusive! */
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Always at most log(n) space needing randomized quicksort variant - with checking for sameconst-arrays */
|
|
static inline void zsrc(uint32_t array[], int low, int high, rpivotstate *state) {
|
|
if (low < high) {
|
|
uint32_t min, max;
|
|
int pi = pick_pivot(state, (high + 1) - low) + low;
|
|
pi = partition_and_minmax_with_pivot(array, pi, low, high, &min, &max);
|
|
if(min != max) {
|
|
/* Recursion with zssort_rand ensures logn+1 stack spacen need! */
|
|
zssort_rand(array, low, pi - 1, state);
|
|
zssort_rand(array, pi + 1, high, state);
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: Idea: Quadratic time happens when you repeatedly pick pivots close to the maximum or minimum - so why not re-pick near extremals being picked which now can be cheked? I think we should have a treshold - maybe dynamically set by first minmax - and logarithmically divide the treshold by 2 in case its still too close the next randomization time. This handles smallrange badly though.
|
|
|
|
// TODO: Guess the pivot value by previous min-maxes and let us use it inn partitioning (which would lead to "closest to pivot value" being swapped to its right position to keep the left:pivot:right separation architecture. Maybe can be faster than rand, although our randoms are pretty darn fast as you can see.
|
|
|
|
// TODO: Hackzolt éjféli ötlet:
|
|
// - Particionálás min-max-avgleft-el
|
|
// - két irányba rekurzió, bal oldalinak avgleft átadása, másik sima zssort_rand
|
|
// - avgleft-es rekurzióból visszahívás ennek a jelenleginek a fő függvényére (ide-oda típusú rekurzió!)
|
|
// - esetleg ha megéri, akkor avgright kiszámítása is jó lehet: drágább műveletek, de jobb algoritmus... hmmm
|
|
|
|
#endif /* ZS_SORT_H */
|