diff --git a/space_partitioning_sort/spsort.h b/space_partitioning_sort/spsort.h index 3e6f23c..6482006 100644 --- a/space_partitioning_sort/spsort.h +++ b/space_partitioning_sort/spsort.h @@ -134,55 +134,39 @@ inline void spsort(uint32_t *t, int n, int m = 32); /** Helper function that puts elements higher then mid to the top of the array and lower to the bottom. Returns number of bottoms */ inline int internal_array_separate(uint32_t *t, int n, uint32_t mid) { - /* - // Init left-right "write head" indices - int left = 0; - int right = n - 1; - uint32_t current = t[left]; - bool current_is_left = true; - - // Separate to the ends of the array (in-place) - for(int i = 0; i < n; ++i) { - if(current < mid) { - const auto tmp = t[left]; - t[left++] = current; - current = current_is_left ? t[left] : tmp; - current_is_left = true; - - } else { - const auto tmp = t[right]; - t[right--] = current; - current = tmp; - current = !current_is_left ? t[right] : tmp; - current_is_left = false; + if(n > 0) { + // Two heads that also read & write (both) + int left = 0; + int right = n - 1; + while(left < right) { + bool lok = (t[left] < mid); + bool rok = (t[right] >= mid); + if(lok || rok) { + // HOT PATH + // Move heads until both in wrong location + left += lok; + right -= rok; + } else { + // REGULAR PATH + // Both in wrong location - xchg them! + auto tmp = t[right]; + t[right] = t[left]; + t[left] = tmp; + ++left; + --right; + } } + + // Edge-case increment if single elem happens in middle in the end + left += ((left == right) && (t[left] < mid)); + + return left; } - return left; - */ - - // FIXME: bad quality debug code to remove - std::vector v(n); - int left = 0; - int right = n - 1; - auto current = t[0]; - for(int i = 0; i < n; ++i) { - if(current < mid) { - v[left++] = current; - current = t[i + 1]; - } else { - v[right--] = current; - current = t[i + 1]; - } - } - for(int i = 0; i < n; ++i) { - t[i] = v[i]; - } - - return left; + return 0; } -// TODO: [spsort] In-place variant that looks like a quicksort-kind-of-thing: +// ALGO: [spsort] In-place variant that looks like a quicksort-kind-of-thing: // - I realized that in-placing make this similar to quicksort actually // - We check if the thing is small enough for insertion sorting in-place // - If not, we calculate low-mid-high @@ -205,6 +189,7 @@ inline void internal_spsort(uint32_t *t, int n, int m, uint32_t low, uint32_t mi // Makes small arrays sort fast otherwise we need to go down m == 2 or such! if(n < m) { binsertion_sort(t, n); + return; } auto left = internal_array_separate(t, n, mid);