堆排序(Heap Sort)
是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
动画详解
堆排序构造过程(参见了大佬blog)
1、构造初始堆
2、构造初始堆后,就需要完整的堆排序
平均复杂度
O(nlog n + n) =O
所谓堆排序就是每次取堆的根结点为最大值,然后将最后一个节点作为根节点,进行堆调整,堆排序的时间等于建堆和进行堆调整的时间,所以堆排序的时间复杂度是O(nlog n + n) =O.
相关操作
在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作:
最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
创建最大堆(Build Max Heap):将堆中的所有数据重新排序
堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算
代码展示(C语言)
#include<stdio.h>
void swap(int *p1,int *p2)
{
int t=*p1;
*p1=*p2;
*p2=t;
}
void heapify(int tree[],int n,int i)
{//三个参数分别是表示数组,数组大小,需要调整的根结点的下标
int max=i;
if(i >= n)
return ;//递归出口
int c1=2*i+1;//左孩子下标
int c2=2*i+2;//右孩子下标
if(c1 < n && tree[max]<tree[c1])//当左孩子存在且比根结点大(需要调整)
{
max=c1;
}
if(c2 < n && tree[max]<tree[c2])
{
max=c2;
}
if(max!=i)//那么需要交换
{
swap(&tree[max],&tree[i]);
heapify(tree,n,max);
}
}
void build_heap(int tree[],int n)//建立初始堆
{
int last_node=n-1;
int parent = (last_node - 1)/2;
int i;
for(i=parent ; i>=0 ;i--)
{
heapify(tree,n,i);
}
}
void heap_sort(int tree[],int n)//堆排序
{
build_heap(tree,n);
for(int i=n-1;i>=0;i--)
{
swap(&tree[i],&tree[0]);
heapify(tree , i,0);
}
}
int main()
{
int tree[10];
for(int i=0;i<10;i++)
{
scanf("%d",&tree[i]);
}
heap_sort(tree,10);
for(int i=0;i<10;i++)
{
printf("%d ",tree[i]);
}
return 0;
}
以上
注:该系列其他博文
经典排序算法动画详解----插入排序