堆排序不仅仅可以对整形数组进行排序,扩展一下思维,也可以对结构体数组进行排序。这里就可以用到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