回顧一下計數排序
桶排序,是計數排序的升級版。解決了計數排序遺留的問題,當一組數據的最小值是100的時候,基數排序創建的空間是0-100-n個。浪費了0-100的位置,所以不能再使用0作為起點,但是總所周知程序的數組下標都是從〇開始的。所以我們需要解決的就是這個基數位置。
原理描述
如有數組 [98 80 94 95 85 94 85 84 98 96 95],按照計數排序的規則,我們需要創建的空間數組為0-98 [0,0,0,0,0,0,0,……0] ,但是由于數組中最小值為80,造成了空間的浪費。
對于這種情況,我們需要請出桶排序。我們以80為基數創建一個數組。
image
然后使用計數排序方法操作即可。
代碼實現
Go
package main
import "fmt"
func main() {
//一個數組,其中有許多重復數據。
//numbers := []int{1, 3, 5, 0, 1, 2, 4, 4, 0, 3, 2, 5, 3}
//****為了體現效果,我們重新聲明一個最小值為80的數組。****
numbers := []int{98, 80, 94, 95, 85, 94, 85, 84, 98, 96, 95}
fmt.Printf("排序前:%v\n", numbers)
//統計數組長度
length := len(numbers)
//找出最大值
maxNumber := numbers[0] //默認第一位最大
//****同時找到最小值****
minNumber := numbers[0] //默認第一位最小
//查找對比第二位及其以后的數字,找到最大。
for i := 1; i < length; i++ {
if maxNumber < numbers[i] {
maxNumber = numbers[i]
}
if minNumber > numbers[i] {
minNumber = numbers[i]
}
}
//用最大值減去最小值的差來創建數組。
counters := make([]int, (maxNumber-minNumber)+1) //由于數組的下標從0開始,所以創建數組為 0 - (n-1),創建0-n的數組,需要n+1
//開始計數
for i := 0; i < length; i++ {
//桶排序里邊最重要的就是查找到數據的位置。
counters[numbers[i]-minNumber]++
}
exIndex := 0
fmt.Println("統計數據:")
//展開數組實現排序
for number, count := range counters {
fmt.Printf("統計到%d個:%d\n", count, number+minNumber) //顯示統計到的數據
//展開數組實現排序
for i := 0; i < count; i++ {
numbers[exIndex] = number + minNumber
exIndex++
}
}
//fmt.Printf("統計數據:\n", counters)
fmt.Printf("排序后:%v\n", numbers)
}
Python
# -*- coding: UTF-8 -*-
numbers = [98, 80, 94, 95, 85, 94, 85, 84, 98, 96, 95]
print("排序前:", numbers)
# 找出數據最大值
maxNum = numbers[0]
minNum = numbers[0]
for num in numbers:
if num > maxNum:
maxNum = num
if num < minNum:
minNum = num
# 聲明統計數組
counters = [0] * (maxNum - minNum + 1)
# 開始計數
for num in numbers:
counters[num - minNum] += 1
# 統計完畢,展開數組
sortIndex = 0
for num in range(minNum, maxNum + 1):
while counters[num - minNum] > 0:
numbers[sortIndex] = num
sortIndex += 1
counters[num - minNum] -= 1
print("排序后:", numbers)
長按二維碼關注我們