实现了不稳定计数排序,那么我们考虑稳定性的计数排序该如何实现呢?
首先,假如有这样一个数组:
那么我们能够获取到它的最小值为1,最大值为6。
根据最小值与最大值创建计数数组,并得到计数数组中各个位置的值,如下:
1. 思考
计数数组中的值为对应数字出现的次数,如果我们将计数数组从头开始,
使 当前索引处的新的值 = 当前索引处的原始值 + 上一索引处的值,得到:
那么现在这个新值代表什么呢?很明显,代表我这个数在排序后数组中 最后出现的索引 + 1。
比如1这个数字在原数组中出现了2次,因为它是最小值,那么它在排序后数组中 最后出现的索引 为1;对于数字2,它出现了1次,计数数组更新后的值为3,说明它在排序后数组中 最后出现的索引 为2;
而对于数字3,原数组中一次都没有出现,而现在它对应计数数组更新后的值也为3,是否会出现问题呢?当然不会。因为我们需要加入判断条件,判断是否出现了这个数字。如果这个数字没有出现,那么它所对应的计数数组更新后的值根本不会用到,丝毫不会对排序产生影响。
2. 思路
好了,经过上面的思考,我们是不是感觉有些 拨开云雾见天日 了呢。
① 确定初始计数数组;
② 对计数数组进行更新;
更新后的计数数组,代表 当前计数数组索引 对应的 原数组数字 在排序后数组出现中 最后出现的索引 + 1。
③ 因为要考虑稳定性问题,而现在更新后的计数数组元素值代表数字最后出现的索引 + 1;那么我们可以先创建一个与原数组等长的辅助数组 assistance;
④ 对原数组 从后往前 遍历,得到数字对应的最后出现索引,根据该索引将其放到 assistance 数组中对应的索引处,然后计数数组中的值-1;
⑤ 遍历结束,assistance 数组就是原数组排序后的结果。
可以选择是否将 assistance 数组 复制到 原数组 中去。
3. 代码
只需要根据上篇博客:计数排序(不考虑稳定性)(Java代码实现)(一)中的代码往后添加方法就行。
//更新计数数组
public static void updateCount() {
//说明计数数组长度为1
if