Instead of that while-loop, I'd use a for-loop and use the common loop/index variable i.
Instead of a separate status variable, I'd simply use i % 2.
I'd deduplicate the two cases.
Putting the current two array elements into variables avoids duplicating the longer array[i] and array[i + 1] and simplifies the swap.
As Joop Eggen points out, it's probably ...
I agree with your analysis that both algorithms have O(n) time complexity (where n is the number of elements in the array). An important factor to note is that both algorithms also use constant extra space.
However, you can include other metrics in your analysis too. Anything that may be expensive to do can be considered. Two common metrics are the number ...
I think you might be able to get a marginal boost by implementing this in two steps: move all the 1s to the end, set everything before to 0. Your current alternate is: count 0s, write 0s, write 1s.
public static void SortOnesZeros(int input)
var oneCursor = input.Length - 1;
for (var i = oneCursor; i >= 0; i--)
if (input[i] == 1)...
This is not a review, but an extended comment.
Theoretically you are right, a time complexity of the first approach is \$O(n)\$. However, there is also a space complexity, also \$O(n)\$, due to the Map, and the map is a very heavyweight data structure. Even though it promises a constant time access, it is only an amortized constant time, and the constant ...
From a short review;
ascending should probably be a parameter in the sortFunc
sort (sortKey) should probably be a parameter in the sortFunc
I feel things should be Spartan (1 char) or spelled out
sortFunc -> sortFunction -> sorter?
I would strongly consider the closure concept (example ion proposal)
I would harmonize the sort values with the object ...