Array.Sort in with nontrivial comparison function
algorithm, c#, lambda, sorting
Solution
Although Array.Sort specifies
If the partition size is fewer than 16 elements, it uses an insertion sort algorithm.
it does not specifiy how it does this insertion sort or which flavor of insertion sort it uses. As already mentioned, it additionally specifies
This implementation performs an unstable sort
and as a result, the only thing `Array.Sort` promises about the order of the elements after returning is that they are sorted. This is true for `{3, 5, 1, 2, 4}`.
Consider that the algorithm used by `Array.Sort` would even be allowed to do something like this (Pseudocode):
if sequence = {1, 2, 3, 4, 5} then
sequence := {3, 5, 1, 2, 4}
end if
Sort(sequence);
This, of course, would be implementation defined behavior, and it could change in another version of the .NET framework.
Modifying your code to be
Array.Sort(numbers, (x, y) =>
{
Console.WriteLine(x + ", " + y);
return x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1;
});
will give you the comparisons that are done by `Array.Sort`:
1, 3
1, 5
3, 5
1, 3
3, 5
2, 3
3, 4
3, 3
5, 3
5, 3
5, 5
5, 3
2, 4
2, 1
4, 2
1, 4
4, 4
4, 2
1, 2
1, 2
1, 1
1, 2
1, 1
And this, very likely, is not how you would do an insertion sort on paper.
The point is: `Array.Sort` promises to sort your sequence, but it does not promise how to do this.
Problem
Consider the following code from C# 5.0 in a Nutshell, p. 289: ``` int[] numbers = { 1, 2, 3, 4, 5 }; Array.Sort (numbers, (x, y) => x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1); ``` which gives result `{3, 5, 1, 2, 4}`. I tried this on a paper and got `{1, 3, 5, 2, 4}`. Why computer sorting gave `3 > 5 > 1` ?