时间复杂度:O(n log n)
- 最好:O(n log n)
- 最坏:O(n log n)
空间复杂度:O(1)
- 只需要一个额外空间用于数据交换
原理
堆排序(Heaps Sort)是指利用堆这种数据结构所设计的一种不稳定排序算法。
堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
- 大顶堆(大根堆):每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
- 小顶堆(小根堆):每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
实现
- 创建一个堆,将数据放在堆中存储。
- 按大顶堆构建堆,其中大顶堆的一个特性是数据将被从大到小取出,将取出的数据元素按照相反的顺序进行排列,数据元素就完成了排序。
- 然后从左到右,从上到下进行调整,构造出大顶堆。
- 入堆完成之后,将堆顶元素取出,将末尾元素置于堆顶,重新调整结构,使其满足堆定义。 ```go
func heapSort(slice []int) []int { if len(slice) < 2 { return slice }
// 从数组内倒数第一个根节点开始,将数组堆化
for i := len(slice) / 2; i >= 0; i-- {
maxHeapify(slice, i, len(slice)-1)
}
// 1.将堆顶数据与尾部数据交换
// 2.从新堆化,将堆顶数据下压
end := len(slice) - 1
for end > 0 {
slice[0], slice[end] = slice[end], slice[0]
end--
maxHeapify(slice, 0, end)
}
return slice
}
// 小顶堆 堆化 func minHeapify(slice []int, root, end int) { for { min := root l := (root << 1) + 1 if l <= end && slice[l] < slice[min] { min = l }
r := l + 1
if r <= end && slice[r] < slice[min] {
min = r
}
if min == root {
break
}
slice[root], slice[min] = slice[min], slice[root]
root = min
}
}
// 大顶堆 堆化 func maxHeapify(slice []int, root, end int) { for { max := root l := (root << 1) + 1 if l <= end && slice[l] > slice[max] { max = l }
r := l + 1
if r <= end && slice[r] > slice[max] {
max = r
}
if max == root {
break
}
slice[root], slice[max] = slice[max], slice[root]
root = max
}
} ```