上一篇有关堆排序的源码是从STL标准库中抽出来,但是源码有点让我混乱。最近闲来无事,再写一篇有关堆排序的博客,并附上简单的过程描述。

  (参考书籍:《算法引论 —— 一种创造性方法》 4.7和6.4.5节)

  堆排序最坏情况下的运行时间是O(n log n)。堆排序中建堆方式有两种:

  1. 自顶向下建立大根堆。简单点说,就是从无到有插入元素到堆中。这样可以有效地维护了大根堆的性质,即大根堆是由满足大根堆性质的子堆构成。

  2. 自底向上建立大根堆。一般都是从堆存储数组的一半的位置开始递减比较。需要注意的是,在每次比较后,需要调整子堆来满足大根堆的性质。有点类似于从建好的大根堆中移除元素之后的调整。(这种方式参考《数据结构(C语言版)》 严蔚敏,吴伟民著的10.4.3节)

  通过上述资料会发现,自顶向下建立大根堆的方式要比自底向上建立大根堆的方式简单。这里使用的是第一种方式:

 1 void build_heap( int heap[], int current_size )
 2 {
 3     int start = 0;
 4
 5     while ( start < current_size - 1 )
 6     {
 7         // start在insert_to_heap函数会发生变化
 8         insert_to_heap( heap, &start, start + 1, heap[start] );
 9     }
10 }

  在建立堆之后,堆排序的处理:只需要将大根堆中的最大值(heap[0])从堆中移除,并将其插入到数组的末尾(升序方式)。

 1 void heap_sort( int heap[], int current_size )
 2 {
 3     int i = current_size - 1;
 4     int j = current_size;
 5
 6     build_heap( heap, current_size );
 7     while ( j )
 8     {
 9         int data = remove_max_from_heap( heap, &j );
10         heap[i] = data;
11         --i;
12     }
13 }

  完整的源码:

  1 #include <stdio.h>
  2 #include <assert.h>
  3
  4 void swap_value( int heap[], int lhs, int rhs )
  5 {
  6     int tmp = heap[lhs];
  7     heap[lhs] = heap[rhs];
  8     heap[rhs] = tmp;
  9 }
 10
 11 /** @*current_size: 表示heap中已经存在的元素个数。
 12  ** @heap_size:表示heap的最大容量是多少
 13  */
 14 void insert_to_heap( int heap[], int *current_size,
 15                      int heap_size, const int value )
 16 {
 17     int child = *current_size;
 18     int parent = 0;
 19
 20     assert( *current_size < heap_size );
 21     heap[child++] = value;
 22     parent = child / 2;
 23     while ( parent >= 0 )
 24     {
 25         if ( heap[child] > heap[parent] )
 26         {
 27             swap_value( heap, child, parent );
 28             child = parent;
 29             parent /= 2;
 30         }
 31         else
 32             parent = -1;
 33     }
 34     *current_size += 1;
 35 }
 36
 37 int remove_max_from_heap( int heap[], int *current_size )
 38 {
 39     int result = 0;
 40     int child = 0;
 41     int parent = 0;
 42
 43     if ( *current_size == 0 )
 44     {
 45         printf( "remove_max_from_heap: the heap is empty.\n" );
 46         return -1;
 47     }
 48
 49     result = heap[0];
 50     swap_value( heap, 0, *current_size - 1 );
 51     --*current_size;
 52     child = 1;
 53     while ( child <= *current_size - 1 )
 54     {
 55         if ( child < *current_size - 1
 56             && heap[child] < heap[child + 1] )
 57         {
 58             child += 1;
 59         }
 60
 61         if ( heap[child] > heap[parent] )
 62         {
 63             swap_value( heap, child, parent );
 64             parent = child;
 65             child *= 2;
 66         }
 67         else
 68         {
 69             child = *current_size;
 70         }
 71     }
 72
 73     return result;
 74 }
 75
 76 void build_heap( int heap[], int current_size )
 77 {
 78     int start = 0;
 79
 80     while ( start < current_size - 1 )
 81     {
 82         insert_to_heap( heap, &start, start + 1, heap[start] );
 83     }
 84 }
 85
 86 void heap_sort( int heap[], int current_size )
 87 {
 88     int i = current_size - 1;
 89     int j = current_size;
 90
 91     build_heap( heap, current_size );
 92     while ( j )
 93     {
 94         int data = remove_max_from_heap( heap, &j );
 95         heap[i] = data;
 96         --i;
 97     }
 98 }
 99
100 int main()
101 {
102     int heap[] = { 78, 58, 87, 62, 92, 332, 55, 40, 75, 146 };
103     int heap_size = sizeof(heap) / sizeof(int);
104     int i = 0;
105
106     heap_sort( heap, heap_size );
107     while ( i < heap_size )
108     {
109         printf( "%d ", heap[i++] );
110     }
111
112
113     return 0;
114 }

View Code

转载于:https://www.cnblogs.com/life91/p/3393644.html

[算法 笔记]堆排序(续)相关推荐

  1. 算法笔记-堆排序(C版本)

    算法笔记-堆排序 作者:星河滚烫兮 前言   本文重点关注堆排序代码的实现,因为注释写的比较详细,大家可以结合代码与注释学习.堆排序其实就是利用二叉堆这种数据结构的特性进行排序,二叉堆又分为最大堆(大 ...

  2. 算法笔记(胡凡)学习笔记@Kaysen

    本文旨在记录算法笔记学习过程中的收获和一些知识点,部分易错知识点只针对个人而言,CCF-CSP考试冲鸭!!! Chapter 2 C/C++快速入门(易错知识点) 2.1 基本数据类型 变量定义注意区 ...

  3. 数据结构与算法笔记(青岛大学王卓老师视频)

    写在前面的话: 因为在学习数据结构之前,学习过一年的算法,所以有一些基础,一些我觉得 没必要的代码或知识就没写上,记得多是一些知识点,写的可能对于别人来说 很难接受,望谅解.我学习算法是在Acwing ...

  4. codeup墓地目录(算法笔记习题刷题笔记)

    在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门模拟->简单模拟 ...

  5. 算法笔记知识点整理大全

    每次刷题都觉得自己吃了知识点不全,基础不牢固的亏,刷题的时候目标也不明确,于是看完了算法笔记并把知识点归纳了一下,当然直接看书会更加详细,这个归纳只是学习时加深印象以及方便自己之后回顾而已:之后刷题大 ...

  6. 算法笔记学习PAT甲级解题记录

    算法笔记学习记录 2019.06.26 float&&double 推荐全部使用double,注意区分scanf("%lf",&double1);与prin ...

  7. 考研算法笔记(排序)

    考纲 (只考虑内部排序) 1插入排序(直插(稳),希尔) 2交换排序(冒泡(稳),快排) 3选择排序(简选,堆排) 4归并排序(稳) 5基数排序(稳) 6算法笔记 对任意n个关键字排序的比较次数至少为 ...

  8. JS数据结构与算法 笔记

    JS数据结构与算法笔记 前言:不定时更新说明 1. 栈(Stack) 1.1 基于数组实现栈 1.2 基于对象实现栈 1.3 基于链表实现栈 1.4 栈的简单应用 1.4.1 字符串中的括号匹配问题 ...

  9. 《算法笔记》——笔记

    算法笔记 胡凡 曾磊 主编 机械工业出版社 文章目录 算法笔记 C/C++快速入门 提醒 memset sscanf与sprintf 引用 浮点数的比较 圆周率 复杂度 黑盒测试 入门篇(1)--入门 ...

最新文章

  1. 详解深度学习中的Normalization,不只是BN(2)
  2. Servlet 流程控制
  3. [转]关于凸优化的一些简单概念
  4. Python高能小技巧:用海象操作符减少重复代码
  5. 【学术研究】保持高效论文写作的10个原则!
  6. 程序员修炼之道(一)
  7. 小米笔记本pro lol测试软件,小米笔记本Pro 15增强版游戏性能测评
  8. 文档管理系统mindoc安装
  9. 人工智能和溯因推理 AI的历史一直被演绎和归纳所主导
  10. setup maven plugin connection
  11. kali里的powersploit、evasion、weevely等工具的杂项记录
  12. java人机猜拳模块流程图_基于java实现人机猜拳游戏
  13. css前端日记之盒子模型-----一起去未来
  14. 三万字总结╰(*°▽°*)╯ 计算机网络 知识点汇总
  15. 实数截断式保留两位小数
  16. 虚拟机 安装 CUDA 可行性说明
  17. 2020年笔记本电脑计算机专业,适合女生用的笔记本电脑排名2020
  18. 校招----shein一面面经
  19. 电脑重装系统Win10“initpki.dll”加载失败怎么办?
  20. 快讯 | 第80届金球奖揭晓

热门文章

  1. 【SSL】【Apache】 配置 https/ssl
  2. echarts如何获取后端的值_Echarts 获取后台数据 使用后台数据展示 柱形图
  3. 商品审核网页界面_商品模块数据库表解析(二)
  4. 农村信用社计算机基础知识,2014年云南省农村信用社考试计算机基础知识练习题...
  5. keras冻结_[开发技巧]·keras如何冻结网络层
  6. tcp接口测试工具_你不了解的,完整“接口测试”与服务虚拟化
  7. 循环结果添加到集合_Java Note-数据结构(4)集合
  8. shell+mysql获取数据库名_shell操作mysql数据库
  9. arcgis 圈选获取图层下点位_ArcGIS小技巧——提取面要素的质心点
  10. anaconda 命令