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.
89 lines
2.4 KiB
89 lines
2.4 KiB
3 years ago
|
# 堆排序
|
||
|
|
||
|
* **介绍**
|
||
|
* `定义`
|
||
|
* 堆是一种特殊的完全二叉树结构
|
||
|
* 大根堆:一棵完全二叉树满足任意节点的值都比孩子结点大
|
||
|
* 小根堆:一棵完全二叉树满足任意节点的值都比孩子结点小
|
||
|
* 堆的向下调整`性质`
|
||
|
* `目的`其实就是一个排序的过程
|
||
|
* `体现`通过向下调整实现获得大根堆
|
||
|
* `总结`当根节点的左右子树都是堆时,但是根不满足堆,可以通过一次向下的调整来将其变换成一个堆。
|
||
|
* 复杂度O(n log(n))
|
||
|
* 思路: 通过建立堆,并重复使用向下调整的性质进行数据排序。
|
||
|
* 过程:
|
||
|
* `1`建立堆
|
||
|
* `2`得到堆顶元素为最大元素
|
||
|
* `3`去除堆顶,将堆`最后元素(原因是保证堆成立)`放到堆顶,此时可以通过一次调整重新是堆有序.
|
||
|
* `4`堆顶元素为第二大元素
|
||
|
* `5` 可以`重复3`直到堆变空
|
||
|
* 关键字:
|
||
|
* 构建堆(农村包围城市)
|
||
|
* 向下排序
|
||
|
* 实现排序:完全二叉树 `>` 堆 `>` 向下调整 `>` 输出元素
|
||
|
* 存在问题
|
||
|
* 在快的排序算法在相对较慢
|
||
|
* 快速排序 `>` 归并排序 `>` 堆排序
|
||
|
* 应用
|
||
|
* 实现解决top-K问题
|
||
|
* top-K对比
|
||
|
* 排序后切片 O(n log(n))
|
||
|
* 排序LowB三人组 O(kn)
|
||
|
* 堆排序思路 O(n log(k))
|
||
|
* **原理**
|
||
|
|
||
|
>
|
||
|
|
||
|
* **代码**
|
||
|
|
||
|
```go
|
||
|
|
||
|
/**
|
||
|
Heap 进行排序
|
||
|
1. 建堆
|
||
|
2. 交换值并向下调整
|
||
|
*/
|
||
|
func Heap(li []int) []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)
|
||
|
}
|
||
|
return li
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
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 // 将临时值放回
|
||
|
|
||
|
}
|
||
|
|
||
|
```
|
||
|
|