forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
1.2 KiB
57 lines
1.2 KiB
package main
|
|
|
|
// 堆排序
|
|
func main() {
|
|
|
|
var a = []int{29, 10, 14, 37, 25, 18, 30} // 创建数组的简写声明
|
|
Heap(a)
|
|
|
|
for _, i2 := range a {
|
|
print(i2, "\t") // 输出每一个值
|
|
}
|
|
}
|
|
|
|
/**
|
|
Heap 进行排序
|
|
1. 建堆
|
|
2. 交换值并向下调整
|
|
*/
|
|
func Heap(li []int) {
|
|
n := len(li)
|
|
for i := (n - 2) / 2; i >= 0; i-- { // 创建堆
|
|
sift(li, i, n-1)
|
|
}
|
|
|
|
for i := n - 1; i >= 0; i-- { // 先做交换(减少内存)后做向下调整
|
|
li[0], li[i] = li[i], li[0]
|
|
sift(li, 0, i-1)
|
|
}
|
|
}
|
|
|
|
/**
|
|
sift 向下调整
|
|
li 数组列表
|
|
low 堆的根节点的下标
|
|
high 堆的最后一个元素的下标
|
|
*/
|
|
func sift(li []int, low, high int) {
|
|
/**
|
|
i 指一层中的根
|
|
j 开始是左孩子
|
|
t 指一层中某个需要调整的值
|
|
*/
|
|
i, j, t := low, 2*low+1, li[low]
|
|
for j <= high { // 在范围内进行循环,防止越界
|
|
if j+1 <= high && li[j+1] > li[j] { // 比较一个根下的两个孩子大小,取大值的位置
|
|
j = j + 1
|
|
}
|
|
if li[j] > t { // 与指定根值比较,若值比根大,继续循环
|
|
li[i], i, j = li[j], j, 2*i+1
|
|
} else {
|
|
// li[i] = t // 将临时值放回,移至循环结束位置
|
|
break
|
|
}
|
|
}
|
|
li[i] = t // 将临时值放回
|
|
|
|
}
|
|
|