/** * Sort algorithm for nearly-sorted data. * * Runtime: * - Worst case O(n^2) [smallrange / descending] * - random case O(nlogn) * Space: same as runtime */ #include // can do with malloc only if needed but this spares more ram. Also can do with a stack data type.. #include // 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 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--]; } } } }