堆排序应该是八种排序中相对较复杂的排序了,当初刚学的时候也是一头雾水,经过自己反复的思考
理解,敲写,终于是弄明白了。
首先堆排序也是一种不稳定的排序,其时间复杂度:最好情况:O(nlogn) 最坏情况:O(nlogn) 平均情况 O(nlogn)
空间复杂度 O(1)
堆排序思想:首先要把序列建成一个完全二叉树,把这棵树改造成堆,如果按照大堆来表示的话,所有子节点都
小于父节点,通过父节点与子节点比较,把大的放在父节点上,一层一层比较,最终找到最大值,也就是堆顶元素
接着与最后一个交换位置,接着对剩余的再进行改造交换,直到所有节点都输出,排序完成。
堆排序代码如下:
#include<stdio.h>
#include<stdlib.h>
void Maxheap(int a[],int start, int end) //按大堆 一层一层往上使父节点大于子节点
{
int child;
int temp;
for(temp = a[start]; 2*start + 1 <end; start = child) //子节点的位置 2*start+1 要小于总长度
{
child = 2*start + 1;
if(child + 1 < end && a[child] < a[child+1]) //左孩子节点与右孩子节点比较 找出大的那一个
{
++child;
}
if(a[start] < a[child]) // 与父节点进行比较
{
a[start] = a[child];
a[child] = temp;
}
else break;
}
}
void Heapsort(int a[],int len)
{
int j;
for(j = len/2-1; j >=0; j--)
{
Maxheap(a,j,len); // len/2-1 最后一个非叶子节点
}
for(j = len - 1; j > 0; j--) // 当前a[0]为最大值与最后一个进行对换
{
int temp = a[j];
a[j] = a[0];
a[0] = temp;
Maxheap(a,0,j); //交换之后可能会破坏原有堆 所以递归 重置堆
}
}
int main()
{
int i;
int a[]={9,8,34,65,23,0,57};
int length = sizeof(a)/sizeof(a[0]);
Heapsort(a,length);
for(i = 0; i < length; i++)
{
printf("%d ",a[i]);
}
printf("\n");
return 0;
}