本博文源于浙江大学《数据结构》,今天姥姥讲的堆排序是利用堆的数据结构进行实现,仔细分析堆排序的复杂度和核心思想,无非是如下几条原理:
堆排序复杂度分析
O(NlogN)
O(1)的空间复杂度
建初堆比较次数:4n
重建堆比价次数:2nlogn
算法特点:
不稳定排序
只能用于顺序结构,不能用于链式结构
初始建堆所需的比较次数较多,因此记录较少不应该采用,
最坏复杂度nlogn 相对于快速排序最坏是一个优点,当记录较多时较为高效
核心思想
利用最大堆(或者最小堆)输出堆顶元素,即最大值(或最小值),将剩余元素重新生成最大堆(或者最小堆),继续输出堆顶元素,重复此过程,直到全部元素都已输出,得到的输出元素序列极为有序序列。
代码思想
将一个无序的序列生成一个最大堆,只要将它与堆的最后一个元素兑换位置即可,然后将调换后的最大值不用管,然后进行生成剩余的最大堆,每次过滤出最大值,将最小堆变成最大堆,实现最大堆的收集过程,采用这种过程就是利用堆的完全二叉树的性质,效果较为显著,如果大家不能理解堆,我这里写好堆的操作集可供查阅(附上链接):
(c语言)堆的创建增加删除源码(包含测试用例)
然后给出测试用例
测试用例
int arr[5] = {5,3,1,6,2};
将整型数组作为容器,5只是一个大小,可供大家随意更改包括里面的元素。
附上源码
//堆排序
//选择排序
#include<stdio.h>
typedef int ElementType;
void Print_Array(ElementType A[],int N)
{
printf("\n");
for(int i=0;i<N;i++)
printf("%d ",A[i]);
}
void Swap(int *X,int *Y)
{
int tmp = *X;
*X = *Y;
*Y = tmp;
}
void PercDown(ElementType A[],int p,int N)
{
int Parent,Child;
ElementType X;
X = A[p];
for(Parent = p;(Parent*2+1)<N;Parent=Child) {
Child = Parent * 2+1;
if((Child != N-1) && (A[Child]<A[Child+1]))
Child ++;
if(X>=A[Child]) break;
else
A[Parent] = A[Child];
}
A[Parent] = X;
}
void Heap_Sort(ElementType A[],int N)
{
int i;
for(i=N/2-1; i>=0;i--)
PercDown(A,i,N);
for(i=N-1;i>0;i--)
{
Swap(&A[0],&A[i]);
PercDown(A,0,i);
}
}
int main()
{
int arr[5] = {5,3,1,6,2};
Print_Array(arr,5);
Heap_Sort(arr,5);
Print_Array(arr,5);
return 0;
}