上一篇说了计数排序,一种稳定的排序,时间复杂度是指数级,可是,计数排序不适用于跨度很大或者浮点数,那么有没有能够处理浮点类型的稳定排序呢?桶排序就是。算法
首先说一下桶排序的桶是什么概念,这里的“桶”是一个区间范围,里面能够承载一个或多个元素。桶排序的第一步就是肯定桶的个数和区间。具体的创建多少个桶、每一个桶的区间范围是多少,有不一样的方式,咱们这里使用桶的数量等于原始数列的元素的数量(为何等于数列的数量,后面会讲到)。除了最后的一个桶只包含最大值,其余的值分散在其余桶里。数组
区间跨度 = (最大值-最小值)/ (桶的数量 - 1)app
第二步是把原始数列的元素放入桶中code
第三步是桶内的元素进行排序排序
第四步就是遍历全部的桶,输出元素element
0.5,0.84,2.18,3.25,4.5it
上面是思路,具体代码以下:class
def sortBucket(array): max = array[0] min = array[0] for i in array: if max < i: max = i if min > i: min = i # 1.初始化桶 bucketNumber = len(array) bucketArray = [] for i in range(bucketNumber): t = [] bucketArray.append(t) # 2.数列的元素放入桶 for i in array: index = int((i - min) / (max - min) * (bucketNumber - 1)) bucketArray[index].append(i) # 3.桶内的元素排序 for i in array: bucketArray[i].sort() # 4.返回排好序的集合 sortedArray = [] for bucket in bucketArray: for element in bucket: sortedArray.append(element) return sortedArray if __name__ == '__main__': array = [3, 3, 3, 7, 9, 1, 7, 1, 3, 4] bucketArray = sortBucket(array) print(bucketArray)
输出结果遍历
[1, 1, 3, 3, 3, 3, 4, 7, 7, 9] Process finished with exit code 0
这里有一个不是很是明白的地方,就是 第二步中数列元素放入桶,计算index的算法:当前差值/全局差值*数列的长度减一(按照比例定位),在网上也看了其余的文章,有的文章里计算index的算法直接是:当前差值/数列长度。而后,我代入了几个元素,发现,仍是前者的算法计算出来的下标更加精确。im
假设原始数列的元素个数是N,桶的数量的M,平均每一个桶内的元素数量的N/M
求最值,计算量N
初始化桶,计算量M
数列的元素放入桶,计算量N
每一个桶内元素排序,因为使用了O(n log n)算法,计算量是M(N/M * log N/M)=N(log N/M)
最后返回排好序的集合,计算量是N
综上所述,计算量是 3N+M+ N(log N - log M),去掉系数O(N+M+N(log N - log M))
假如M=N,则时间复杂度O(N+M),近似O(N)
空间复杂度:很明显是原始数组的空间N 加上 桶的空间M,是N+M
假如元素分布极不均衡,好比所有在最后一个桶内,则此时的时间复杂度就退化到了O(n*log n),而且空间复杂度浪费了不少,由于建立了不少无用的空桶