一、堆的概念

所谓堆,它是一个数组,也能够被看成一个近似的全然二叉树。树上每一个结点相应数组的一个元素。二叉堆分为二种:最大堆和最小堆。本文主要介绍最大堆,最小堆类似。最大堆的特点:对于随意某个结点,该结点的值大于左孩子、右孩子的值,可是左右孩子的值没有要求。

二、堆排序算法

首先,按堆的定义将数组R[0..n]调整为堆(这个过程称为创建初始堆),交换R[0]和R[n];

然后,将R[0..n-1]调整为堆,交换R[0]和R[n-1];

如此反复,直到交换了R[0]和R[1]为止。

以上思想可归纳为两个操作:

(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。

这里可以利用完全二叉树的结构,从最后一个非终端节点开始对子元素进行排序筛选。

(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。

当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。

  具体图片我就不找了,网上很多。

三、算法比较

堆排序算法的时间复杂度是O(nlgn),比插入排序要好,跟归并排序相同,但是与归并排序不一样的地方在于,堆排序不需要额外的存储空间,或者说,只需要常数个额外的存储空间,属于内排序算法。

#include <stdio.h>
#define N 1000
#define INF 999999999
int h[N];
//调整堆(迭代法)
//n:规模 i:二叉子堆的堆顶
void
heapAdjust(int n, int par)
{
int tmp, pos, lc, rc; while (par <= n/) {
tmp = h[par]; //记录父母结点键值
lc = par<<;
rc = lc+;
pos = par;
//父母结点至多更新2次
if (h[par] < h[lc]) {
h[par] = h[lc];
pos = lc;
}
if (rc <= n && h[par] < h[rc]) {
h[par] = h[rc];
pos = rc;
}
if (pos == par) //无更新即无需调整
break;
else
h[pos] = tmp;
par = pos; //假设这个位置的结点是“父母结点”
}
} //创建堆
//规模为n的堆,对其父母结点,自底向上自右向左地调整堆
void
createHeap(int n)
{
int i; for (i = n/; i != ; i--) {
heapAdjust(n, i);
}
} void
heapSort(int n)
{
int ntimes = n; while (ntimes--) {
printf("%d\n", h[]);
h[] = h[n];
h[n--] = ; //堆清零
heapAdjust(n, );
}
} int
main(void)
{
int n, i; scanf("%d", &n);
h[] = INF;
for (i = ; i != n+; i++) {
scanf("%d", &h[i]);
}
createHeap(n);
heapSort(n);
return ;
} /*
参考测试数据
6
342 31 52 626 12 124
10
43 525 14 21 52 3 52 45 319 15155
*/

堆排序(C语言实现)的更多相关文章

  1. 堆排序-C语言实现

    堆排序 堆排序是利用堆的性质进行的一种选择排序.下面先讨论一下堆. 1.堆 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i ...

  2. 高速排序,归并排序,堆排序python实现

    高速排序的时间复杂度最好情况下为O(n*logn),最坏情况下为O(n^2),平均情况下为O(n*logn),是不稳定的排序 归并排序的时间复杂度最好情况下为O(n*logn),最坏情况下为O(n*l ...

  3. STL容器底层数据结构的实现

    C++ STL 的实现: 1.vector      底层数据结构为数组 ,支持快速随机访问   2.list            底层数据结构为双向链表,支持快速增删   3.deque     ...

  4. [转]STL 容器一些底层机制

    1.vector 容器 vector 的数据安排以及操作方式,与 array 非常相似.两者的唯一区别在于空间的运用的灵活性.array 是静态空间,一旦配置了就不能改变,vector 是动态数组.在 ...

  5. 堆排序(Heap Sort)的C语言实现

    堆排序(Heap Sort)具体步骤为 将无序序列建成大顶堆(小顶堆):从最后一个非叶子节点开始通过堆调整HeapAdjust()变成小顶堆或大顶堆 将顶部元素与堆尾数组交换,此是末尾元素就是最大值, ...

  6. Go语言用堆排序的方法进行一千万个int随机数排序.

    上篇文章用的是quicksort方法排序,可是假设用高速排序法对反复率非常高的slice排序的时候,时间复杂度会激增,速度相当慢 所以尝试了一下堆排序,实验结果,感觉挺好的.以下是代码,大家能够參考一 ...

  7. c语言数据结构之 堆排序

    算法:先生成随机数,赋值到数组,将数组第一个元素a[0]设置为哨兵,函数调用数组和随机数个数n,再设定n/2的根结点与孩子结点进行比较操作,若右孩子存在,则选出三个数里最小的数赋值给根节点,如果右孩子 ...

  8. 排序算法c语言描述---堆排序

    排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析. 文章规划: 一.通过自己对排序算法本身的理解,对每个方法写个小测试程序.具体思路分析不 ...

  9. 深入浅出数据结构C语言版(19)——堆排序

    在介绍优先队列的博文中,我们提到了数据结构二叉堆,并且说明了二叉堆的一个特殊用途--排序,同时给出了其时间复杂度O(N*logN).这个时间界是目前我们看到最好的(使用Sedgewick序列的希尔排序 ...

  10. 堆排序(大顶堆、小顶堆)----C语言

    堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...

随机推荐

  1. Spring—Ioc

    IoC容器,最主要的就是完成对象的创建以及维护对象的依赖关系等. 所谓控制反转,包括两部分:一是控制,二是反转,就是把传统方式需要由代码来实现对象的创建.维护对象的依赖关系,反转给容器来帮忙管理和实现 ...

  2. iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  3. 修改JS文件都需要重启Idea才能生效解决方法

    最近开始使用Idea,有些地方的确比eclipse方便.但是我发现工程每次修改JS或者是JSP页面后,并没有生效,每次修改都需要重启一次Tomcat这样的确不方便.我想Idea肯定有设置的方法,不可能 ...

  4. BZOJ 2005: [Noi2010]能量采集(莫比乌斯反演)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2005 题意:   思路: 首先要知道一点是,某个坐标(x,y)与(0,0)之间的整数点的个数为gcd ...

  5. LA 3938 动态最大连续和(线段树)

    https://vjudge.net/problem/UVALive-3938 题意:给出一个长度为n的整数序列D,你的任务是对m个询问作出回答.对于询问(a,b),需要找到两个下标x和y,使得a≤x ...

  6. 癌症免疫细胞治疗知识:CAR-T与TCR-T的区别在哪里?--转载

    肿瘤免疫治疗,实际上分为两大类.一种把肿瘤的特征“告诉”免疫细胞,让它们去定位,并造成杀伤:另一种是解除肿瘤对免疫的耐受/屏蔽作用,让免疫细胞重新认识肿瘤细胞,对肿瘤产生攻击(一般来说,肿瘤细胞会巧妙 ...

  7. QWebEngineView_CssVariables

    1.测试代码,参考网址:http://blog.sina.com.cn/s/blog_1508519340102wgq0.html 2.测试下来,结果: 2.1.Qt5.6开始,没有 WebKit了. ...

  8. [java]java String.split()函数的用法分析

    转自:http://swiftlet.net/archives/709 一.在java.lang包中有String.split()方法的原型是: public String[] split(Strin ...

  9. EBS 定义并发参数常用值集

    1.ORG_ID 2.DATE 3.YES_NO

  10. html中用变量作为django字典的键值

    若字典为dic={'name': Barbie, 'age': 20},则在html中dic.name为Barbie,dic.age为20. 但若字典为dic={'Barbie': 1, 'Roger ...