clllll  

堆排序

通过数组构造堆,
根节点是最大的元素 是大根堆,相反为小根堆
主要有俩个方法,插入 InsertHeap , 调整 堆: heapify

对于排序来说:先把数组构造成一个大根堆,然后[0] 依次和最后的元素交换。直到0.这样就排好序了。
image
image

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)如果堆中还有剩余元素,依次弹出

后面补充。。代码

posted on 2023-01-22 15:49  llcl  阅读(102)  评论(0编辑  收藏  举报