这是最后一个学习的排序算法,之前的排序算法都是基于比较的思路形成的,而该排序算法是数据的状况来确定的。(不是基于比较的)时间复杂度为O(N),额外空间复杂度为O(M)。
目录
桶排序下的思想
1. 计数排序
前提:该排序的方式如同前文所说,是基于一定的数据情况的。
比如:对11100003332222排序。
我分别装每一类的数。然后对桶进行排序,那么原来的序列就牌好序了。
2. 基数排序
基数排序的算法同计数排序一样,它也是基于桶的思想。
该思想是对序列的每一个位(个位、十位、百位)进行装桶的过程。
例如:对17,13,5,25,100排序
1)每个元素补齐到最多的位数。017,013,005,025,100
2)将个位数相同的数放在一个桶里面
桶0:100 桶3:013 桶5:005、025 桶7:017
3)再把数字按照桶的顺序倒出来,形成:100、013、005、025、017 的顺序。
(注意思考在实现过程中怎样才能实现这个顺序)
...重复按照个位、百位的要求进行入桶、出桶的过程。
最终按照最高位出桶的顺序就是排号序的顺序。
桶排序
因此,基于基数排序,继续学习桶排序的思想。
入桶:
首先定义一个count数组,该数组的index=0、1、2、3...9位上分别代表数值为0、1、2、3...9的相应位数(个位、十位、百位)的个数。
比如对于017,013,005,025,100。在第一轮中(个位),那么该数字index=0上的值为1,因为有一个个位的数字100。
出桶(排序):
从右向左遍历整个序列(017,013,005,025,100)。把该序列的值放在新的数组(help)中进行储存。
例如,(在入桶结束后,count的序列为:1,0,0,1,0,2,0,1,0,0)
从个位开始,从右向左出桶,第一个数为100,那么放在help数组中的位置就是count[0]=1,放在help[1]的位置上。之后,count[0]--,以便有下一个个位为0的数要出桶。
然后继续下一个数字025,就放在help[2]的位置上。(count[5]=2)。
继续后面的数字直到个位排序完成。
当个位排序完成后,还需要重新给count赋值(入桶),和排序(出桶),直到每位数都排好了。
最后的结果就是正确的序列。
(注意,该过程的入桶、出桶与前面讲的基数排序的思想相同,只是在实现中,需要不同的数组来进行这个过程,不然光看思想的话会认为序列就放在一个桶中。)
为什么要从右向左出桶?
可以看到我前面在说基数排序的时候,提醒注意如何实现这个按照过程(出桶后就是按照一定顺序排的)。
仔细想想,发现只有从右向左出桶(给help赋值),才能找到每个数对应的index值。
也就是说count如果的数如果大于1,(有多个数的某一位相同),那么这些数的顺序就和遍历它们的顺序相关。(从左往右是一种顺序,从右往左又是一场顺序)。
个人姑且认为,该思想与我们习惯的从大到小划分的思维习惯不同。它是从局部有序到整体有序的过程)。