堆排序之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

原文地址:https://www.cnblogs.com/zcqkk/p/9645295.html