堆排序之golang实现扩展版本
堆排序不仅仅可以对整形数组进行排序,扩展一下思维,也可以对结构体数组进行排序。这里就可以用到interface和闭包了。golang给我们提供了很大的遍历。
针对每种数据结构体,可以定制闭包,例如:使用按个成员进行比较。
package main
import (
"fmt"
)
func adjustHeap(a []interface{}, pos int, lenght int, cmp func(a, b interface{}) bool) {
for {
// 计算孩子位置
child := pos*2 + 1
// 检查孩子是否越界
if child >= (lenght - 1) {
break
}
// 找出孩子中较大的那个
if cmp(a[child], a[child+1]) {
child++
}
// 检查孩子是否大于父亲,如果大于则交换
if cmp(a[pos], a[child]) {
// 父子交换
a[pos], a[child] = a[child], a[pos]
// 更新位置,指向子节点
pos = child
} else {
// 如果子节点都小于父节点了,那就可以结束调整了
break
}
}
}
func buildHeap(a []interface{}, cmp func(a, b interface{}) bool) {
// 从底层向上层构建,len(a)/2-1是第一个非叶子
for i := len(a)/2 - 1; i >= 0; i-- {
adjustHeap(a, i, len(a), cmp)
}
}
func heapSort(a []interface{}, cmp func(a, b interface{}) bool) {
// 构建大顶堆
buildHeap(a, cmp)
fmt.Println("buildHeap over:", a)
fmt.Println("===============================")
// 首尾交换,重新构建大顶堆
for i := len(a) - 1; i >= 0; i-- {
a[0], a[i] = a[i], a[0]
adjustHeap(a, 0, i, cmp)
}
}
func main() {
num := []interface{}{98, 48, 777, 63, 57, 433, 23, 1112, 1}
heapSort(num, func(a, b interface{}) bool {
a1 := a.(int)
b1 := b.(int)
return a1 < b1
})
fmt.Println("heap sort over:", num)
}
参考:https://www.jianshu.com/p/774b097d6f81

浙公网安备 33010602011771号