golang中有一些关于桶排序的代码。
但是,我遇到了关于长度为 10 的索引超出范围 [10] 的恐慌。
我发现
bucketIdx := int((v - minValue) / bucketSize)
有一些问题。因为 (v - minValue) / bucketSize
应该是 9.9999999999。然而,int((v - minValue) / bucketSize)
将是10。我是golang的新学习者。不知道怎么解决。
您可以在此处运行这些代码演示
这是源代码。
package main
import "fmt"
func bucketSort(array []float64) []float64 {
// Determine minimum and maximum values
minValue, maxValue := array[0], array[0]
for _, v := range array {
if v < minValue {
minValue = v
} else if v > maxValue {
maxValue = v
}
}
// Initialize buckets
bucketSize := (maxValue - minValue) / 10
bucketCount := 10
buckets := make([][]float64, bucketCount)
// Distribute elements into buckets
for _, v := range array {
bucketIdx := int((v - minValue) / bucketSize)
buckets[bucketIdx] = append(buckets[bucketIdx], v)
}
// Sort buckets and place back into input array
i := 0
for _, bucket := range buckets {
insertionSort(bucket)
for _, v := range bucket {
array[i] = v
i++
}
}
return array
}
func insertionSort(array []float64) {
n := len(array)
for i := 1; i < n; i++ {
value := array[i]
j := i - 1
for j >= 0 && array[j] > value {
array[j+1] = array[j]
j--
}
array[j+1] = value
}
}
func main() {
array := []float64{0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434}
fmt.Println("Sorted Array: ", bucketSort(array))
}
感谢您的时间和考虑。
实际上,我尝试过使用 math.Floor() 来解决这个问题。但还是没有运行。
bucketSize := (maxValue - minValue) / 10
、 (v - minValue) / bucketSize
生成值 [0...10]。
要生成值 [0...10)(注意
)
),需要进行不同的计算。
鉴于我们使用的是浮点数,边缘情况值得考虑。考虑到浮点数学的有限精度及其各种舍入模式,上面提到的 [0...10] 可能确实是 [略小于 0 ... 略大于 10]。
为了避免特殊的边缘情况处理,而不是
bucketSize
1/10 范围,请考虑 1/(n-1)
或 1/9。然后将指数计算平移0.5。
n = 10 - 1
bucketSize := (maxValue - minValue) / n
...
// v--- 0 to 9.0 ------------v
bucketIdx := int((v - minValue) / bucketSize + 0.5)
// ^--- 0.5 to 9.5 ----------------^
// ^------- 0 to 9 ---------------------^
它确实使末端桶的平均填充量是中间桶的一半,但我们不需要特殊的边缘测试。
如果
(maxValue - minValue) / n
的任何部分溢出,则需要额外考虑。