上一篇說了計數排序,一種穩定的排序,時間複雜度是指數級,可是,計數排序不適用於跨度很大或者浮點數,那麼有沒有能夠處理浮點類型的穩定排序呢?桶排序就是。算法
首先說一下桶排序的桶是什麼概念,這裏的「桶」是一個區間範圍,裏面能夠承載一個或多個元素。桶排序的第一步就是肯定桶的個數和區間。具體的創建多少個桶、每一個桶的區間範圍是多少,有不一樣的方式,咱們這裏使用桶的數量等於原始數列的元素的數量(爲何等於數列的數量,後面會講到)。除了最後的一個桶只包含最大值,其餘的值分散在其餘桶裏。數組
區間跨度 = (最大值-最小值)/ (桶的數量 - 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),而且空間複雜度浪費了不少,由於建立了不少無用的空桶