堆排序
通过数组构造堆,
根节点是最大的元素 是大根堆,相反为小根堆
主要有俩个方法,插入 InsertHeap , 调整 堆: heapify
对于排序来说:先把数组构造成一个大根堆,然后[0] 依次和最后的元素交换。直到0.这样就排好序了。
package basicsort
import "fmt"
func HeapSort(arr []int) {
//构造堆
for i := 0; i < len(arr); i++ {
InsertHeap(arr, i)
}
fmt.Println(arr)
// 开始把最大值依次替换到后面
size := len(arr) // 记录当前堆的大小
for i := len(arr) - 1; i > 0; i-- {
swap(arr, 0, i)
fmt.Println(i, arr)
size-- //堆的大小减一
//[0] 和最后一个数替换,当前堆已经不是大根堆了。要调整。
heapify(arr, size)
fmt.Println(i, arr)
}
}
func InsertHeap(arr []int, index int) {
//插入堆
for arr[index] > arr[(index-1)/2] {
//如果自己比自己的父节点大,那么就交换
swap(arr, index, (index-1)/2)
index = (index - 1) / 2 //更新index的值
}
}
func heapify(arr []int, size int) {
for i := 0; i < size; {
// 判断自己和自己的左右节点 谁大,
//先判断 是否存在 左右节点,超过堆大小就不是了。
max_index := i //保存最大值的索引
//这里是小于,不是小于等于。 比如 size 是 9 ,但是索引到8 。。
if i*2+1 < size && arr[i*2+1] > arr[max_index] {
//左子节点存在,并且比父节点大,更新max_index
max_index = i*2 + 1
}
if i*2+2 < size && arr[i*2+2] > arr[max_index] {
//右子节点存在, 更新max_index
max_index = i*2 + 2
}
// 结束条件: i就是max_index
if i == max_index {
break
}
//交换
swap(arr, i, max_index)
i = max_index // 更新i的值。
}
}
堆排序扩展
对一个几乎有序的数组,几乎有序指的是:每个元素移动到正确的位置不超过k.请选择一个合适的排序算法
1)先把k个元素 入堆。
2)再次入堆的时候,就要弹出元素了
3)如果堆中还有剩余元素,依次弹出
后面补充。。代码