您的位置:首页 > 理论基础 > 数据结构算法

数据结构之堆排序C语言实现

2016-07-12 09:44 225 查看
堆排序:

时间复杂度:O(nlogn)

稳定性:不稳定

实现原理:将待排序的序列构造成一个大顶堆(或小顶堆) 整个序列的最大值就是堆顶的根节点,将它移走 (就是将其与对数组的末尾元素交换,此时末尾元素就是最大值)。然后将剩余的n-1个序列重新

构成一个堆,这样就会的到n个元素中 的最大值如此反复执行,得到一个有序序列。

大顶堆:根节点是最大者

小顶堆:根节点是最小者

大顶堆满足条件:K[i]>=K[2*i+1] 且K[i]>=K[2*i+2] (0<=i<=n/2-1) K[i]为堆顶 K[2*i+1]为堆顶左子树 K[2*i+2]为堆顶的右子树

小顶堆满足条件:K[i]<=K[2*i+1] 且K[i]<=K[2*i+2] (0<=i<=n/2-1)

实现步骤:

1.先将初始文件R[1..n]建成一个大顶堆,此堆为初始的无序区

2. 再将关键字最大的记录R1和无序区的最后一个记录R
交换,

3. 由此得到新的无序区R[1..n-1]和有序区R
,且满足R[1..n-1].keys≤R
.key

4. 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。

5.然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,

6.由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n- 2].keys≤R[n-1..n].keys,

7.同样要将R[1..n-2]调整为堆。

…… 直到无序区只有一个元素为止

大顶堆排构建的基本操作:

初始化操作:将R[1..n]构造为初始堆;

每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

小顶堆的构建与大顶堆相反

//代码实现:
#include <stdio.h>
#inlude <stdlib.h>
/****************************************************************************
功能:实现大顶堆的构建
输入参数: int i:起始操作的元素的下标
2*i+1:表示i的左子树下标
2*i+2:表示i的右子树小标
int len:需要构建大顶堆的数组的长度
返回值:无
*******************************************************************************/
void HeapAdjust(int a[],int i,int len)
{
while( 2*i+1 < len )
{
int maxindex=2*i+1; //将最大的下标初始化为s的子树下标
if(2*i+2<len)
{
//比较左子树和右子树,记录最大值的Index
if(a[2*i+1]<a[2*i+2])
{
maxindex=2*i+2;
}
}
if(a[i]<a[maxindex])
{
//交换i与maxindex的数据
a[i]=a[i]^a[maxindex];
a[maxindex]=a[i]^a[maxindex];
a[i]=a[i]^a[maxindex];
//堆被破坏,需重新调整
i=maxindex;
}
else
{
//比较左右孩子均大则堆未破坏,不再需要调整
break;
}
}
return;
}
//堆排序
void HeapSort(int a[],int len)
{
int i=0;
//将a[0,Len-1]建成大顶堆
for(i=len/2-1;i>=0;i--)
{
//调用构建大顶堆函数
HeapAdjust(a,i,len);
}
//只需做n-1趟排序
for(i=len-1;i>0;i--)
{
//将字最大的记录R[1](即堆顶)和无序区的最后一个记录R
交换
a[0]=a[0]^a[i];
a[i]=a[0]^a[i];
a[0]=a[0]^a[i];
//将a[0..i]重新调整为大顶堆
HeapAdjust(a,0,i);
}
return;
}
int main(int argc, char const *argv[])
{
int a[]={45,569,213,123,12,56,45,56,10};
HeapSort(a,9);
int i;
for(i=0;i<9;i++)
{
printf("%d ",a[i]);
}
printf("\n");
return 0;
}


编译运行结果正确,如果有错误,欢迎指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息