在早些的文章中,我们讲过了常见的比较排序算法,详情请回顾:
小白学数据结构——四、排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)
那么我们这次就来看一些不是基于比较的排序算法,包括了桶排序,计数排序,基数排序。
1.桶排序
说起桶排序,就先来介绍一下我们加下来要用的桶,说的就是下面这个桶(当然不是用来装垃圾的),桶盖表示游标index,桶身上表示该游标下的数据data,没错,可以看做数组中的一个元素
假设我们需要排序数组A=【4 ,-1,0,3,3】这5个数字,我们需要怎么做呢?
把大象放进冰箱需要分几步?
1.把冰箱门打开
2.把大象装进去
3.把冰箱门关上
同样的道理,我们也需要思考三个问题:
1.我们需要多少个桶?
2.怎么把原数据放进桶里?
3.怎么把数据从桶里拿出来?
Q:那我们需要多少个桶呢?
答案是我们max-min+1个桶。
当然这样说不够生动,我们直接看上面的数组A,它需要4 -(-1)+ 1= 6个桶,就是把从-1到4的所有数全部遍历一遍共有-1,0,1,2,3,4这6个数,所以需要6个桶
我们把这么多桶也当做一个数据,它有游标(在它的桶盖上),还有数据(桶身),data中记录元素出现的次数
Q:怎么把原来的数据装进桶里呢?
实际上,桶里面装的不是A数组的元素,而是数组中元素出现的次数,比如我们C中下标为0记录A中最下的数组元素出现的次数(即-1出现的次数)。出现次数为1次,所以C[0]=1
同理,C[1]记录A中第二小的数组元素出现的次数(即0出现的次数),所以C[1]=1
我们的桶后来就变成了:
也就是说A[i]会使C[A[i] - min]的值加1。(C中下标index用A[i] - min表示)
Q:怎么把数据从桶里拿出来?
这个很简单,既然C中下标index用A[i] - min表示,那么C中的值不为0的时候,输出C[i]个i+min就好了,这样讲还是不够生动,直接来个栗子
比如当i为4的时候,C[i]的值为2,说明输出2次,输出两次的数字就是i+min,就是4+(-1)=3,即输出两个3。
这样输出的数字当然是有序的了,而且没有和其他数字进行比较。
详细