本文只是自己的筆記,並不具備過多的指導意義。
代碼的初衷是便於理解,網上大神優化過的代碼很多,也不建議在項目中copy本文代碼。
目錄
- 桶排序
- 記數排序
- 基數排序
- 桶排序
桶排序
桶排序並不是一個具體的排序,而是一個邏輯概念。
之所以叫桶,是因爲他會根據數據狀況設計出一個容器,裏面每個index將相當於一個桶。
在遍歷數據的時候將根據劃分將數據一次放入每個桶中,遍歷結束後將桶依次倒出。
在每個桶內部,數據會被處理成有序結構。
具體操作可以參考記數排序。
-
桶排序的特點
- 非基於比較的排序,與被排序的樣本的實際數據狀況很有關係。
並不能作爲一個通解被應用在普遍場景下,所以實際中並不經常使用。 - 時間複雜度O(N),額外空間複雜度O(N)
- 穩定的排序
記數排序
桶排序的具體實現,根據數據狀況的最大值開闢一個容器空間
核心在於將數據值轉化爲鍵存儲在額外開闢的容器空間中。
數據遍歷完成,將容器空間的數據填充給原數組。
/// 計數排序
///
/// - Parameters:
/// - arr: 目標數組
/// - max: 最大值
func countingSort(arr : inout [Int] ,max:Int) {
var containerArr = [Int](repeating: 0, count: max+1) //生成長度爲最大值的容器數組
var p = 0
while p<arr.count {
containerArr[arr[p]]+=1 //容器數組指定位置計數+1
p+=1
}
p = 0
var containerP = 0 //容器數組遍歷指針
while containerP<max { //遍歷容器數組
while containerArr[containerP]>0 { //如果容器數組指定位置大於0
arr[p] = containerP //依次將容器數組的index填充回目標數組
p+=1
containerArr[containerP]-=1
}
containerP+=1
}
}
算法的時間複雜度O(N),空間複雜度O(N),並且穩定
基數排序
也是桶排序的一種實現,相比記數排序堆桶的利用更加精緻。
具體實現上,從個位數開始,逐位進行排序。由於每次partition都是穩定的,從而保證整體有序。
通俗點來講,百位相同的數,按照十位排序,十位相同的數按照個位排序。
/// 基數排序
///
/// - Parameters:
/// - arr: 目標數組
/// - maxDigit: 最大位數
func radixSort(arr: inout [Int] ,maxDigit: Int) {
var mod=10 //取餘
var containerArr = [[Int]](repeating: [Int](repeating: 0, count: 0), count: 9) //創建一個長度爲9的二位容器數組
while mod<=kt_pow(a: 10, b: maxDigit) { //取餘位數 小於等於 最大位數 100/10 <=10^2
var p = 0
while p < arr.count { //在容器數組中,將原數組以某位的值進行排列
//獲取某位的值
let bucket = arr[p]%mod/(mod/10) // 120%100=@20 ==> @20/(100/10) = 2
containerArr[bucket].append(arr[p]) //加入有序數組的指定位置
p+=1
}
p = 0
while p < arr.count { //將容器數組中的順序,回倒給原數組
for index in 0..<containerArr.count {
while containerArr[index].count>0 { //將容器數組指定位置的元素依次出隊
arr[p] = containerArr[index][0] //首位出隊
containerArr[index].remove(at: 0) //移除首位
p+=1
}
}
}
mod*=10 //對下一位進行排序
}
}
/// 乘方運算
///
/// - Returns: a^b
func kt_pow(a:Int ,b:Int) -> Int {
var a=a
let c=a
if b == 0 {
return 1
}
var i = 1
while i<b {
a=a*c
i+=1
}
return a
}
算法的時間複雜度O(N),空間複雜度O(N),並且穩定
桶排序
網上有寫了桶排序的,就是通過有限個數的桶,將數據源按區間放入,然後將某個桶內部排序。最後倒出。
感覺在桶內部排序的時候已經需要比較的排序方式了,違背了初衷吧。
有興趣自己可以看一下
十大經典排序算法(動圖演示)