前言:
,“堆”(Heap)是一种特殊的树。堆这种数据结构的应用场景非常多,最经典的莫过于堆排序了。堆排序是一种原地的、时间复杂度为 O(nlogn) 的排序算法。
1. 什么是堆
- 堆是一个完全二叉树;
- 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。
2. 堆的实现和常见操作
完全二叉树比较适合用数组来存储。
存储思路:数组中下标为 i 的节点的左子节点,就是下标为 i∗2 的节点,右子节点就是下标为 i∗2+1 的节点,父节点就是下标为 2i 的节点。
2.1 往堆中插入一个元素
思路:
golang代码实现:
2.2 删除堆顶元素
思路:
golang代码实现:
3. 如何实现堆排序
3.1 堆化
思路:
golang代码实现:
//小顶堆堆化
func minHeap(root int, end int, c []int) {
for {
child := 2*root + 1
//判断是否存在child节点
if child > end {
break
}
//判断右child是否存在,如果存在则和另外一个同级节点进行比较
if child+1 <= end && c[child] > c[child+1] {
child += 1
}
if c[root] > c[child] {
c[root], c[child] = c[child], c[root]
//继续向下比较
root = child
} else {
break
}
}
}
//大顶堆堆化
func maxHeap(root int, end int, c []int) {
for {
child := 2*root + 1
//判断是否存在child节点
if child > end {
break
}
//判断右child是否存在,如果存在则和另外一个同级节点进行比较
if child+1 <= end && c[child] < c[child+1] {
child += 1
}
if c[root] < c[child] {
c[root], c[child] = c[child], c[root]
//继续向下比较
root = child
} else {
break
}
}
}
3.2 排序
思路:
golang代码实现:
package main
import "fmt"
//小顶堆堆化
func minHeap(root int, end int, c []int) {
for {
child := 2*root + 1
//判断是否存在child节点
if child > end {
break
}
//判断右child是否存在,如果存在则和另外一个同级节点进行比较
if child+1 <= end && c[child] > c[child+1] {
child += 1
}
if c[root] > c[child] {
c[root], c[child] = c[child], c[root]
//继续向下比较
root = child
} else {
break
}
}
}
//降序排序
func HeapMinSort(c []int) {
var n = len(c) - 1
for root := n / 2; root >= 0; root-- {
minHeap(root, n, c)
}
fmt.Println("小顶堆构建完成")
for end := n; end >= 0; end-- {
c[0], c[end] = c[end], c[0]
minHeap(0, end-1, c)
}
}
//大顶堆堆化
func maxHeap(root int, end int, c []int) {
for {
child := 2*root + 1
//判断是否存在child节点
if child > end {
break
}
//判断右child是否存在,如果存在则和另外一个同级节点进行比较
if child+1 <= end && c[child] < c[child+1] {
child += 1
}
if c[root] < c[child] {
c[root], c[child] = c[child], c[root]
//继续向下比较
root = child
} else {
break
}
}
}
//升序排序
func HeapMaxSort(c []int) {
var n = len(c) - 1
for root := n / 2; root >= 0; root-- {
maxHeap(root, n, c)
}
fmt.Println("大顶堆构建完成")
for end := n; end >= 0; end-- {
c[0], c[end] = c[end], c[0]
maxHeap(0, end-1, c)
}
}
func main() {
arr := []int{3, 1, 8, 7, 2, 5, 4, 6}
HeapMinSort(arr)
fmt.Printf("after heap min sort is: %v\n", arr)
arr = []int{3, 1, 8, 7, 2, 5, 4, 6}
HeapMaxSort(arr)
fmt.Printf("after heap max sort is: %v\n", arr)
}