magyarsort/outliersort.h

52 lines
1.4 KiB
C
Raw Normal View History

2023-07-20 23:28:52 +02:00
/**
* Sort algorithm for nearly-sorted data.
*
* Runtime:
* - Worst case O(n^2) [smallrange / descending]
* - random case O(nlogn)
* Space: same as runtime
*/
#include <vector> // can do with malloc only if needed but this spares more ram. Also can do with a stack data type..
#include <cstdint> // uint32_t
// TODO: outliersort(...) function with parametrizable "what is an outlier?" and "init" functions!
// why? Because when I renamed outnsi to outlier I realized the only rule is to keep the begin
// of the array sorted but otherwise we better put into the outlier data that would make us
// less likely to be able to fill-in more data points (think of real outliers like [1 9000 2 3 4 ...8999]
// TODO: simple to make this work with custom comparator and type..
void nsort(uint32_t *arr, int n) {
// Temp space - worst case O(n) size
std::vector<uint32_t> outlier;
// Split [i: read, j: write]
uint32_t max = (n > 0) ? arr[0] : 0;
uint32_t i = 1;
uint32_t j = 1;
while(i < n) {
if(arr[i] < max) {
outlier.push_back(arr[i++]);
} else if(i > j) {
arr[j++] = arr[i++];
}
}
if(outlier.size() > 1) {
// Recursion
nsort(&outlier[0], outlier.size());
// Merge-from-right [j: sorted right-index, i: write index]
uint32_t k = outlier.size() - 1;
--j;
--i;
while(i >= 0) {
if(outlier[k] > arr[j]) {
arr[i--] = outlier[k--];
} else {
arr[i--] = arr[j--];
}
}
}
}