Last active
December 20, 2024 00:39
-
-
Save GrabYourPitchforks/1eef0eb7dba297f70fe6cc23eb88069a to your computer and use it in GitHub Desktop.
Spoiler - sorting a list of ints in linear time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
// It's a bit naive in that it performs more copies than necessary, but it's clearly linear time. | |
// The extra copies and other overhead can be optimized away if needed. | |
// [Yes, it's a naive implementation of radix sort. :)] | |
static void Sort(Span<uint> span) | |
{ | |
Span<uint> scratch = new uint[span.Length]; | |
for (int i = 0; i < 32; i++) | |
{ | |
OrderByBitPos(span, scratch, i); | |
} | |
static void OrderByBitPos(Span<uint> span, Span<uint> scratch, int bitPos) | |
{ | |
// First copy everything to scratch so that we can write | |
// the ordered result back into the original span. | |
span.CopyTo(scratch); | |
// Forward walk - write everything that has 'bitPos' unset | |
// to the front of the span. | |
int spanIdx = 0; | |
for (int i = 0; i < scratch.Length; i++) | |
{ | |
if ((scratch[i] & (1 << bitPos)) == 0) | |
{ | |
span[spanIdx++] = scratch[i]; | |
} | |
} | |
// Reverse walk - write everything that has 'bitPos' set | |
// to the end of the span. | |
spanIdx = span.Length - 1; | |
for (int i = scratch.Length - 1; i >= 0; i--) | |
{ | |
if ((scratch[i] & (1 << bitPos)) != 0) | |
{ | |
span[spanIdx--] = scratch[i]; | |
} | |
} | |
// At this point, 'span' is ordered in the low (1 << bitPos) bits. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment