数据结构之堆排序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]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
小顶堆的构建与大顶堆相反
编译运行结果正确,如果有错误,欢迎指出。
时间复杂度: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; }
编译运行结果正确,如果有错误,欢迎指出。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 堆排序
- 如何写好 C main 函数
- C#数据结构之顺序表(SeqList)实例详解
- Lua和C语言的交互详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#堆排序实现方法
- C#数据结构之单链表(LinkList)实例详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例