排序算法c语言描述---堆排序
排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析。
文章规划:
一。通过自己对排序算法本身的理解,对每个方法写个小测试程序。具体思路分析不展开描述。
二。通过《大话数据结构》一书的截图,详细分析该算法。
在此,推荐下程杰老师的《大话数据结构》一书,当然不是打广告,只是以一名读者的身份来客观的看待这本书,确实是通俗易懂,值得一看。
ps:一个较为详细的学习链接 http://blog.csdn.net/guo_hongjun1611/article/details/7632047
五。堆排序
一。个人理解
学习堆排序,要了解以下两方面内容。
1.堆的定义
2.堆排序的实现。
1.堆的定义
堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
一。 Key[i]<=key[i+]&&Key[i]<=key[i+] 小顶堆
或者 Key[i]>=Key[i+]&&key[i]>=key[i+] 大顶堆
即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。
由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。
二。 每个结点的左子树和右子树都是一个二叉堆(都是小顶堆或大顶堆)。
满足以上条件的二叉树就是一个堆。
如下图所示,就是一个小顶堆。
2.堆排序的实现。
堆排序是利用堆的性质进行的一种选择排序。
其基本思想为(大顶堆):
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。
不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
具体的演示过程我就不详细介绍了。可以通过阅读下面的《大话数据结构》一书截图系统的学习。
下面直接上代码
#include<stdio.h>
// 打印结果
void Show(int arr[], int n)
{
int i;
for ( i=0; i<n; i++ )
printf("%d ", arr[i]);
printf("\n");
} // 交换数组元素位置
void Swap( int *num_a, int *num_b )
{
int temp = *num_b;
*num_b = *num_a;
*num_a = temp;
} // array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度
void HeapAdjust(int array[], int i, int nLength)
{
int nChild, nTemp;
for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild)
{
// nChild:左子结点的位置是 父结点位置 * 2 + 1 nChild + 1: 右子结点
nChild = 2 * i + 1;
// 得到子结点中较大的结点
if (nChild != nLength - 1 && array[nChild + 1] > array[nChild])
++nChild;
// 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
if (nTemp < array[nChild])
{
array[i] = array[nChild];
}
else // 否则退出循环
{
break;
}
}
// 最后把需要调整的元素值放到合适的位置
array[i] = nTemp;
}
// 堆排序算法
void HeapSort(int array[], int length)
{
// 调整序列的前半部分元素,(即每个有孩子的节点)调整完之后是一个大顶堆,第一个元素是序列的最大的元素
for (int i = length / 2 - 1; i >= 0; --i)
{
HeapAdjust(array, i, length);
}
// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (int i = length - 1; i > 0; --i)
{
// 把第一个元素和当前的最后一个元素交换,
// 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
Swap(&array[0], &array[i]);
// 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
HeapAdjust(array, 0, i);
}
} int main()
{ //测试数据
int arr_test[10] = { 8, 4, 2, 3, 5, 1, 6, 9, 0, 7 };
//排序前数组序列
Show( arr_test, 10 );
HeapSort( arr_test, 10 );
//排序后数组序列
Show( arr_test, 10 );
return 0;
}
可以看下这组测试数据的过程加深理解
一个测试及输出的结果,在每次HeapAdjust之后显示出来当前数组的情况
before Heap sort:
71 18 151 138 160 63 174 169 79 78
// 开始调整前半段数组元素
71 18 151 138 160 63 174 169 79 78
71 18 151 169 160 63 174 138 79 78
71 18 174 169 160 63 151 138 79 78
71 169 174 138 160 63 151 18 79 78
174 169 151 138 160 63 71 18 79 78
// 开始进行全局的调整
169 160 151 138 78 63 71 18 79 174
160 138 151 79 78 63 71 18 169 174
151 138 71 79 78 63 18 160 169 174
138 79 71 18 78 63 151 160 169 174
79 78 71 18 63 138 151 160 169 174
78 63 71 18 79 138 151 160 169 174
71 63 18 78 79 138 151 160 169 174
63 18 71 78 79 138 151 160 169 174
18 63 71 78 79 138 151 160 169 174
二。 《大话数据结构》一书截图分析
注:本文仅为分享知识,绝无商业用途。
如果以该种形式分享知识造成不必要的纠纷,还请第一时间告知。
排序算法c语言描述---堆排序的更多相关文章
- 排序算法c语言描述---冒泡排序
排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析. 文章规划: 一.通过自己对排序算法本身的理解,对每个方法写个小测试程序. 具体思路分析 ...
- 排序算法c语言描述---选择排序
排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析. 文章规划: 一.通过自己对排序算法本身的理解,对每个方法写个小测试程序. 具体思路分析 ...
- 快色排序算法(C语言描述)
快速排序 算法思想 快速排序采用了一种分治策略,学术上称之为分治法(Divide-and-Conquer Method). 哨兵(如下算法中的key) 每趟排序将哨兵插入到数组的合适位置,使得哨兵左侧 ...
- 排序算法C语言实现——堆排序
/*堆排nlog(n)*//*堆排复杂度分析1.建堆((n*log(n))/2) 循环n/2次,每次调用HeapAdjust函数 HeapAdjust内部循环log(n)2.调整堆(((n ...
- 【转】九大排序算法-C语言实现及详解
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
- 几种常见排序算法的C++描述
基本的排序算法有如下特点: 1.几种容易的算法都是以O(N2)排序的 2.Shell排序编程简单,其也是以O(N2)排序的,在实践中用的很多 3.复杂的排序算法往往都是按照O(NlogN)尽心排序的 ...
- 排序算法总结 c描述
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
- 排序算法C语言实现
大学有一门课程叫做数据结构,严蔚敏的课本,其中详细介绍了集中经典的排序算法,学习复习反复几次,但是直到现在仍然只记得名字了,所以想记录下来,随时复习直至牢记于心.经常面试的朋友知道,排序算法在面试中出 ...
- 排序算法C语言实现——冒泡、快排、堆排对比
对冒泡.快排.堆排这3个算法做了验证,结果分析如下: 一.结果分析 时间消耗:快排 < 堆排 < 冒泡. 空间消耗:冒泡O(1) = 堆排O(1) < 快排O(logn)~O(n) ...
随机推荐
- Python: 设计模式 之 工厂模式例(1)
#!/usr/bin/env python #coding=utf-8 # # 工厂模式一例 # 版权所有 2014 yao_yu (http://blog.csdn.net/yao_yu_126) ...
- 2016022603 - redis数据类型
Redis支持5种类型的数据类型 1.字符串:Redis字符串是字节序列.Redis字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你可以存储任何东西,512兆为上限.[类 ...
- spring- properties 读取的五种方式
转至:http://www.cnblogs.com/hafiz/p/5876243.html 方式1.通过context:property-placeholder加载配置文件jdbc.properti ...
- iOS:不同属性声明方式的解析
代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因 ...
- bzoj AC 50 庆祝~~
No. 1050 Solved 50 Submit 212 AC 60 PE 6 WA 88 TLE 13 MLE 5 OLE 2 RE 29 CE 9 10001002100310041005 10 ...
- Matlab读取cifar10 train_quick.sh输出txt中信息
感谢 网友 Vagrant的提醒.之前 一直就看个最后的accuracy.这个应该并不靠谱.最好把说有的信息都看一下.而一个一个看.根本记不住.只能把数据读取在图片中显示一下,才比较直观. 本文就是读 ...
- NEURAL NETWORKS, PART 3: THE NETWORK
NEURAL NETWORKS, PART 3: THE NETWORK We have learned about individual neurons in the previous sectio ...
- touchend与click顺序
http://www.w3cmm.com/javascript/touch.html click 在 touchend之前 去除超链接的虚线框 http://www.cnblogs.com/kingw ...
- CPU 定位高
流程:把线程dump出来,然后分析 1:Threaddump的方法: kill -3 pid jstack -l pid jvisualvm中来thread dump 2:找到导致cp ...
- WITH AS 优化逻辑读
SQL> select * from fxqd_list_20131115_new where (acct_no, oper_no, seqno, trans_amt) not in (sele ...