一、概念
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
堆排序中的堆指选择排序中的无序区间,利用了大根堆(或小根堆)堆顶记录的 关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
二、演示过程
1、初始化大顶堆(对应上图的建大顶堆)
2、将大顶堆顶点(即堆中最大值)加入有序区,通过与无序区的最后一个位置进行交换,有序区多了一个(不再排序),无序区少了一个
3、将无序区进行堆调整
1)检查堆顶点是否比左子树,右子树的根都要大,若不是,将堆顶点与左右子树根的最大值进行交换
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。循环,直到序列有序
3、代码:
func HeapAdjust(a []int){ //调整大顶堆
e := 0
temp := a[0]
for i:=1;i<len(a);i=i*2+1 {
if i<len(a)-1 && a[i]<a[i+1] {
i++
}
if a[i] > temp {
a[e] = a[i]
e = i
} else{
break
}
}
a[e] = temp
}
func HeapInit(a []int){//构造初始堆
for i:=len(a)/2;i>=0;i-- { //从第一个非叶子结点从下至上,从右至左调整结构
HeapAdjust(a[i:])
}
}
func HeapSort(a []int){
HeapInit(a)
for i:= len(a)-1;i>0;i-- {
a[i],a[0] =a[0],a[i]
HeapAdjust(a[:i])
}
fmt.Println(a)
}
func main(){
a := []int{0,10,19,24,61,5,121,9,11,34,21,22}
HeapSort(a)//[0 5 9 10 11 19 21 22 24 34 61 121]
}
O(N*log2N) | O(N*log2N) | O(N*log2N) |