百度得到的堆定义如下:

堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)

当ki <= k2i的时候,称之为小顶堆,反之则称之为大顶堆。堆排序时间复杂度好坏情况均为nlogn,效率在一众排序算法中排得上第二了。此外,在很多面试题中,堆排序是一种非常高效的解决问题手段,比如查找前100万个数中的最大值或者最小值。此时如果使用堆排序的话,不仅满足时间复杂度要求,空间复杂度也可满足。堆排序听起来挺难的,其实实现是相当简单。

堆的图形化显示和二叉树类似,对于小顶堆,任意节点的左右子树都小于它,堆顶为最小元素。对于大顶堆,任意节点都大于其左右子树,堆顶为最大元素,定义上容易理解。堆排序是基于数组的,因为数组下标和它特别匹配。如果使用c语言实现堆排序,注意分配数组的时候多分配一个存储单元,这样就可以直接从下标1开始,免得从0开始还得处理下标问题,得不偿失。

堆的基本操作包括:查询,添加,删除,无序数组初始化建堆等。

1.       先从数组初始化建堆开始,首先要找到堆中最后一个非终端节点,下标为size/2。至于这个值是如何得到的。可以自行计算下,这里给个提示,没有孩子节点或者有一个孩子节点两种情况。得到这个非终端节点下标后,可以从它开始,自下往上调整堆,根据堆的性质(大顶堆或者小顶堆),将当前元素和孩子节点比较,然后调整合适位置。代码比较简单,如下:

//调整s的位置,s+1 ~ end为排好序的堆
void heapAdjust(pheap p, int s, int end)
{int i, j;j = 2 * s;for (;j <= end; j*=2){//这里给出的是大顶堆,如果是小顶堆的话,将比较符号以及下面的操作进行反向处理即可。if (j < end && p->data[j] < p->data[j+1])j++;if (p->data[s] >= p->data[j]) break;swap(p->data + s, p->data + j);s = j;}return ;
}void heapSort(pheap p)
{int i, size = p->len;//从非终端节点,自底向上调整堆for (i = size/2; i >= 1; i--)heapAdjust (p, i, p->len);
}

2.  查询操作,当然就是从顶部开始往下查喽,这点和普通的二叉搜索树查询一样,比较大小,然后再和左右子树比较。

3. 插入操作,通常都是追加到尾部,然后自底向上比较找到合适位置。

4. 删除操作的话,一般都是删除堆顶元素,这时候将堆底元素提到堆顶,然后重新调整堆即可。调整操作于初始化无序数组类似。

以上就是堆排序的内容,相比插入排序、归并排序、快速排序,我觉得堆排序算是相当高效的一种排序算法。此外,相比于利用AVL、红黑树等高级数据结构实现的排序而言,堆排序实现代码特别简洁,和冒泡排序有的一拼,适合手撕排序。

参考资料:

1. 数据结构 : C语言版/ 严蔚敏,吴伟民编著

=============================================================================================

Linux应用程序、内核、驱动开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

堆排序之 大顶堆和小顶堆 c语言相关推荐

  1. 谈谈堆排序,大顶堆,小顶堆

    目录 1.前言 2.使用堆的原因 3.堆的特点 4.堆和普通树的区别 5.堆排序的过程 6.堆排序的代码实现 来源: jianshu.com/p/15a29c0ace73 1.前言 堆是一种非线性结构 ...

  2. 堆排序:大顶堆和小顶堆 + 前K个高频元素

    堆 一.堆排序 小顶堆 举个栗子 大顶堆 二.前K个高频元素 思路分析 三.构造器代码解析 一.堆排序 要了解大顶堆和小顶堆,我们先简单了解一下堆排序. 堆排序(Heapsort)是指利用堆这种数据结 ...

  3. 堆排序(浅谈大顶堆与小顶堆)

    什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被看作一个完全二叉树,通俗来讲堆其实就是利用完全二叉树的结构来维护的一维数组,按照堆的特点可以把堆分为大顶堆 ...

  4. c语言标准模板小顶堆,堆排序(大顶堆、小顶堆)----C语言

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

  5. NO29、最小的K个数(应该记住大顶堆和小顶堆的区别与联系,并不难)

    29.最小的K个数 应该记住大顶堆和小顶堆的区别与联系,并不难 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 示例1 输入 ...

  6. C++大顶堆和小顶堆

    C++大顶堆和小顶堆 原理 大顶堆 小顶堆 大顶堆和小顶堆对比图 大顶堆和小顶堆的实现代码 vector和push_heap.pop_heap实现堆 建堆 调整堆 priority_queue实现堆 ...

  7. 大顶堆和小顶堆-java

    一.大顶堆和小顶堆的原理 1.大顶堆 根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大顶堆.大根堆要求根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值. 2.小 ...

  8. 大顶堆,小顶堆——排序问题

    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 例如, [2 ...

  9. 用Java实现二叉堆、大顶堆和小顶堆

    先了解了解 什么是二叉堆 二叉堆就是完全二叉树,或者是靠近完全二叉树结构的二叉树.在二叉树建树时采取前序建树就是建立的完全二叉树.也就是二叉堆.所以二叉堆的建堆过程理论上讲和前序建树一样. 什么是大顶 ...

最新文章

  1. python代码怎么运行-python代码如何运行
  2. c# 获取cad文档的路径_C# 打开以对话框,获取文件夹路径 、文件的路径、文件名...
  3. Zuul(SpringCloud学习笔记一)
  4. Runtime.getRuntime().exec
  5. js请求结果拦截机器_分享:一步一个脚印,vue入门之axios的应用及拦截封装
  6. 【解题报告+感想感言】2019年第十届蓝桥杯【C++省赛B组】【第五题:迷宫】
  7. Docker添加或者更改容器的端口映射
  8. opp原则_OPP--面向对象知识点
  9. 心语收集14:人生没有如果,但是有很多但是;人生不能后悔,但是可以拐弯。...
  10. expect免互交 常用编辑文本
  11. Python 实现的、带GUI界面的词云生成器
  12. ssh-keygen 指定路径
  13. 从冬奥看中国科技(六):千里光伏初长成
  14. DPCM之预测误差均方值推导最小二乘法总结
  15. walking机器人入门教程-工具-命令管理器
  16. Marshmallow及ORM小结
  17. Win10 点击任务栏固定的文件夹资源管理器就重启
  18. 真正的高手,都懂得构建自己的知识体系
  19. CDOJ1323柱爷的下凡
  20. MyBatis——》转义字符(大于,小于,大于等于,小于等于)

热门文章

  1. JS解析XML文件和XML字符串
  2. springboot 定时器_基于SpringCloud?+?SpringBoot的 SaaS型微服务脚手架源码分享
  3. 2.1 词汇表征-深度学习第五课《序列模型》-Stanford吴恩达教授
  4. 梯度下降法Gradient Descent深度学习 机器学习
  5. STM32 进阶教程 12 - M4的硬件乘法器使用
  6. STM32 基础系列教程 50 – MbedTls
  7. TCL foreach的用法
  8. 成员函数和成员变量分开存储
  9. win10开启wsl系统,让我们愉快的在windows上使用Linux
  10. 我的网盘(云存储)功能需求,免费网盘需求,争取早日和百度网盘说拜拜