Concentrating on the requirement in the question of possibly accepting the input as a stream of integers, one solution would be a modified insertion sort...
Create a list (herein named countlist
) of lists, initially empty. Each time you accept a new value, iterate descending through each list in countlist
, looking for the value. If you find the value in countlist[i]
, remove the value from its current list and insert it into countlist[i+1]
, adding a new list to countlist
if necessary. If you never find the value, insert the value into countlist[1]
.
The purpose of iterating descending instead of ascending is that it allows you to maintain a pointer to where the value will be inserted into countlist[i]
if you find it in countlist[i-1]
. If you do not need a sub-sort on the values that share the same count, you can skip this pointer and iterate ascending.
I believe this algorithm is O(n2) overall. Processing each new value is O(n) and results are kept sorted as you go. At any point, you can print the correct order (so far) by iterating descending through countlist
and printing each list.
Sample run, using the example in the question...
input: 7, 4, 2, 4, 9, 6, 5, 6, 2, 0, 2, 1
After accepting 7:
countlist[1] = 7
After accepting 4:
countlist[1] = 4, 7
After accepting 2:
countlist[1] = 2, 4, 7
After accepting 4:
countlist[1] = 2, 7
countlist[2] = 4
After accepting 9:
countlist[1] = 2, 7, 9
countlist[2] = 4
After accepting 6:
countlist[1] = 2, 6, 7, 9
countlist[2] = 4
After accepting 5:
countlist[1] = 2, 5, 6, 7, 9
countlist[2] = 4
After accepting 6:
countlist[1] = 2, 5, 7, 9
countlist[2] = 4, 6
After accepting 2:
countlist[1] = 5, 7, 9
countlist[2] = 2, 4, 6
After accepting 0:
countlist[1] = 0, 5, 7, 9
countlist[2] = 2, 4, 6
After accepting 2:
countlist[1] = 0, 5, 7, 9
countlist[2] = 4, 6
countlist[3] = 2
After accepting 1:
countlist[1] = 0, 1, 5, 7, 9
countlist[2] = 4, 6
countlist[3] = 2