题外话堆排序比之前的简单选择、冒泡算法、快速排序算法复杂一些,因为用到了树形数据结构,但是本文使用了数组实现完全二叉树,因此也比较简单。C语言初学者,可以简单了解其思想,具体的知识掌握可以参照数据结构等专业课程学习。

ps:昨天因为学习实在太晚,未及时更新,抱歉哈。学习C语言之余,觉得C语言编程,最重要的就是C语言语法+数据结构+算法,掌握这三方面基本上可以应付各种编程问题。

为什么学习排序算法,可以参见前面文章~[C语言必学的12个排序算法:基础知识 (第0篇)]

树形选择排序

  • 选择排序其实可以有简单选择排序、树形选择排序。
  • 其中堆排序是一种高效的树形选择排序。
  • 简单选择排序时间复杂度是O(n^2),每趟子排序需要比较O(n)次。
  • 树形选择排序通过减少每趟子排序比较次数,减少时间复杂度,基本思想是每趟子排序,对整个数据记录关键字重复两两比较(和锦标赛赛制一样),直至选出最小的关键字记录为止,这样每趟子排序只需要比较O(logn)次,重复n次,即可有序,时间复杂度为O(nlogn)。
  • 普通的树形选择排序需要的辅助空间较多、存在多余的比较的缺点,堆排序改进这些缺点,只需要1个辅助空间,堆排序的时间复杂度是O(nlogn),同样也是不稳定的内部排序。
  • 与快速排序比较,优势是最坏的情况,堆排序的时间复杂度同样是O(nlogn),快速排序平均性能比堆排序好,但是最坏情况时间复杂度是O(nlogn)。

堆排序

堆排序涉及的知识点较多,主要包括堆的定义、完全二叉树,对于C语言初学者来说,具体理论知识可以参见《数据结构》相关课本书籍。

1.完全二叉树

叶子结点只能出现在最后一层或倒数第二层的二叉树。通俗来说,树的父节点都有两个孩子结点,除非是最后一层或倒数第二层的父节点可以有1或0个孩子结点。

2.堆定义

堆首先是完全二叉树,根据父节点是否比孩子节点大,分为大顶堆和小顶堆。

大顶堆:完全二叉树中所有的父节点必须大于等于两个孩子结点,这样树的根结点就是整个树结点中最大值。

小顶堆:完全二叉树中所有的父节点必须小于等于两个孩子结点,这样树的根结点就是整个树结点中最小值。

3.排序过程

以从小到大排序为例,对整个数据记录序列初始建立“大顶堆”,然后根结点为最大关键字,和序列最后一个关键字记录交换,继续对剩下的前n-1个记录序列进行调整,重新变成新的“大顶堆”,如此反复,每次可以得到当前子序列最大的关键字,最后即可得到从小到大的序列。

实现要点:

    • 从小到大排序,为节约内存空间和方便实现,使用大顶堆;反之从大到小排序,则用小顶堆。
    • 重新调整建堆的过程称为筛选,完全二叉树父节点从上到下,沿着关键字较大的孩子节点向下调整,遇到比父节点大的孩子结点,则交换。
    • 每次筛选操作后,当前父节点代表的子完全二叉树符合堆的要求,因此对所有父节点筛选后,即可整个符合堆的定义。
    • 初始建堆的过程,相当于对所有父节点从“堆顶”筛选操作。
    • 初始建立堆时,注意完全二叉树最后一个非叶子结点肯定是[n/2]个数据元素,因为其左孩子的结点编号是n/2 * 2 = n,可以从该元素开始调整建立堆,叶子结点无需调整。

代码实现

*/
#include <stdio.h>
// 对范围[low,high]数据记录筛选调整建立堆
void adjust_heap(int a[],int low, int high)
{int t = a[low];int i;// 注意数组下标从0开始// 二叉树结点编号需要从1开始 // 父节点与孩子结点比较大小,沿着元素路径向下for(i=2*(low+1); i<=(high+1); i *= 2){// 比较左右孩子结点,如果右孩子大,选择右孩子 if(i<=high && a[i-1]<a[i])  i++;// 如果父节点已经大于等于孩子结点,则调整结束if(t>=a[i-1]) break;  // 否则调整交换位置// 此时不需要给a[i-1]赋值,节约操作a[low] = a[i-1];low = i-1; } a[low] = t;}
void heap_sort(int a[], int length)
{int i,t; // 初始建成大顶堆 for(i=length/2-1; i>=0; i--){adjust_heap(a, i, length-1);}// 每趟选出最大元素和当前最后一个元素交换,再调整成堆 for(i=length-1; i>=0; i--){t = a[0];a[0] = a[i];a[i] = t;adjust_heap(a, 0, i-1);}
}
int main(void)
{int a[10] = {4,3,1,2,6,5,0,9,8,7};heap_sort(a, 10);int i;for(i=0; i<10; i++)printf("%d ", a[i]);return 0;
}

其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。

c++ sort 从大到小排序_C语言必学的12个排序算法:堆排序(第7篇)相关推荐

  1. c++ sort 从大到小排序_C语言必学的12个排序算法:冒泡排序(第4篇)

    基本思想 冒泡排序(Bubble Sort),是一类"交换"类排序方法,类似水中冒泡,最大的数据会沉到水底,较小的数会浮上来.很简单,以从小到大排序为例,每一趟排序将"逆 ...

  2. c++ 快速排序_C语言必学的12个排序算法:归并排序(第8篇)

    题外话很多童鞋感受算法比较难度,的确,算法其实和C语言本身关系不大,算法是计算机科学家利用丰富的数学和算法设计知识研究出来,如今我们只需拿来主义,学习使用即可,当然这需要一定的努力过程. [C语言必学 ...

  3. 9个元素换6次达到排序序列_C语言必学的12个排序算法:希尔排序(第3篇)

    基本思想 希尔排序(Shell's Sort),以发明人命名,又称为缩小增量排序,也是一种插入排序算法. 主要思想:直接插入排序算法时间和待排数据有关,其平均复杂度是O(n^2),但是在待排数据已经有 ...

  4. C语言必学的12个排序算法:基数排序

    # 基本思想 基数排序(radix sort),同样时一种非比较的内部排序算法,主要基于多关键字排序的思想进行排序,它将单个关键字按照基数分成"多个关键字"进行排序.例如整数789 ...

  5. c 结构体 不允许使用不完整的类型_C语言必学知识点 quot;结构体quot;详细解析!...

    结构体是经常用到的数据类型,使用频率不亚于指针,所以需要重视,不过用法非常简单. 一.什么是结构体 ☀ 在前面的时候已经介绍了C语言中的数组,用法跟其他语言差不多.当一个整体由多个数据构成时,我们可以 ...

  6. aes算法c语言实现_C语言实现常用数据结构:Dijkstra最短路径算法(第18篇)

    「今天是学习C语言第 161 天」 纸上学来终觉浅,绝知此事要躬行.-- 陆游「冬夜读书示子聿」#题外话算法学习重点是学习如何编程使用它. # Dijkstra算法 Dijkstra算法,中文译名迪杰 ...

  7. c++ sort 从大到小排序_算法的艺术:MySQL order by对各种排序算法的巧用

    在 [精华]洞悉MySQL底层架构:游走在缓冲与磁盘之间 这篇文章中,我们介绍了索引树的页面怎么加载到内存中,如何淘汰,等底层细节.这篇文章我们从比较宏观的角度来看MySQL中关键字的原理.本文,我们 ...

  8. c语言实验题——字符串排序,C语言中实现“三个数由小到大排序”的多种方法浅析...

    本文通过一个简单示例"三个数由小到大排序",将C语言中许多知识点融会贯通起来,这多种方法的实现可以将函数.宏.指针之间的区别和本质清晰的展示给读者,使本来很复杂难以理解的概念变得通 ...

  9. 成绩从大到小排序c语言,刚学c语言,老师让用if编一个五个数字从大到小的排序,有那个大神能帮我,谢谢啦...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #define N 5 int main() { int numbers[N]; int i,j,pre,k; int x = 5; i ...

最新文章

  1. antd中的form表单 initialValue导致数据不更新问题
  2. php七牛云储存图片,wordpress使用七牛云存储图片 | 厘米天空
  3. 【转】矩阵变换坐标系 深入理解
  4. Linux下qwt源码编译,QWT的编译与配置
  5. 百度HR发布招聘信息要求“热爱小米文化”?百度回应:冒充的
  6. python 函数特殊属性
  7. jsp if else c标签 总结
  8. 突破变态限制快捷方式提权法
  9. AutoCAD2012官方原版软件下载
  10. 了解Xcelsius2008系统
  11. 软件集成测试采用,集成测试的组成以及流程
  12. 深度学习细颗粒图像分析综述
  13. 腾讯云老用户重新注册新账号算新用户吗?
  14. php函数库快速记忆法_史上最全的php函数大全
  15. 跟着团子学SAP PS-前台篇-WBS元素介绍及相关操作 CJ20N
  16. Scala入门系列(7)-Scala之函数式编程
  17. 1.制作PE系统U盘
  18. 记录CentOS8 开机卡住的问题解决过程
  19. 十分详细的数码管电子时钟(基于51单片机)
  20. 行业短信应用的类型与短信模板

热门文章

  1. windowsterminal设置初始大小_这是我见过最全面的金蝶操作详解了,从初始化到财务使用全流程...
  2. MATLAB学习笔记(十一)
  3. 纯python好找工作吗_Python现在好找工作么?
  4. matlab将图片旋转的代码_【MATLAB】钟表
  5. 计算机基础知识教程 百度,28、如何上网--电脑基础知识
  6. 空间组网(卫星组网)概述
  7. RocketMQ(七)——消息的消费
  8. linux 线程退出资源回收,有关linux线程资源回收的有关问题
  9. odbc如何连oracle数据库,不安装Oracle如何连数据库(odbc驱动)
  10. php网页正文提取,通用网页正文抓取工具_任意网页正文提取API