There's an in-place (MSB) radix sort.
它是这样的:
这个过程是这样的:
↓ ↓
0... 1...
--------------- ---------------
↓ ↓ ↓ ↓
00... 01... 10... 11...
------- ------- ------- -------
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
000 001 010 011 101 110 110 111
--- --- --- --- --- --- --- ---
...
时间复杂度为O(bits*n),空间复杂度为O(bits)。
所以在位数不变的情况下,时间复杂度为O(n),空间复杂度为O(1)。
也可以使用计数排序(具有相同的时间和空间复杂度)来做到这一点。
- 计算每个元素的数量。
- 使用它,您可以确定这些元素应出现在数组中的哪个位置。
创建一个包含上述所有起点的查找表(将索引映射到偏移量,可以是一个数组),用于确定下一个元素应该去哪里。
-
现在您遍历数组并将每个不合适的元素交换到它可以到达的第一个位置,然后对我们交换的每个元素执行相同的操作,直到当前元素位于它所属的位置。
每一步增加相关元素在查找表中的偏移量。
请注意,同一元素不可能交换两次,因此这将是线性时间。
这听起来很令人困惑,所以这里有一个例子:
4 5 3 1 2 3 4 4 1 5 4 3 2 3
// counts:
1: 2, 2: 2, 3: 4, 4: 4, 5: 2
// the starting points (offsets) based on the counts:
1 at position 0
2 at position (offset of 1)+(count of 1) = 0+2 = 2
3 at position (offset of 2)+(count of 2) = 2+2 = 4
4 at position (offset of 3)+(count of 3) = 4+4 = 8
5 at position (offset of 4)+(count of 4) = 8+4 = 12
// sorting:
4 5 3 1 2 3 4 4 1 5 4 3 2 3 // out of place, swap with offsets[4] = 8 (offsets[4]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // in correct position, moving on (offsets[1]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // swap with offsets[5] = 12 (offsets[5]++)
^
1 2 3 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 2 (offsets[2]++)
^
1 3 2 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[3] = 4 (offsets[3]++)
^
1 2 2 1 3 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 3 (offsets[2]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[1]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[2]++)
^
你懂的……
注意,计数表和查找表的大小为O(max value),如果每个数字包含固定位数,则为O(1)。
你为每个元素做固定的工作量,所以这是O(n)时间。