[算法 笔记]堆排序(续)
上一篇有关堆排序的源码是从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
[算法 笔记]堆排序(续)相关推荐
- 算法笔记-堆排序(C版本)
算法笔记-堆排序 作者:星河滚烫兮 前言 本文重点关注堆排序代码的实现,因为注释写的比较详细,大家可以结合代码与注释学习.堆排序其实就是利用二叉堆这种数据结构的特性进行排序,二叉堆又分为最大堆(大 ...
- 算法笔记(胡凡)学习笔记@Kaysen
本文旨在记录算法笔记学习过程中的收获和一些知识点,部分易错知识点只针对个人而言,CCF-CSP考试冲鸭!!! Chapter 2 C/C++快速入门(易错知识点) 2.1 基本数据类型 变量定义注意区 ...
- 数据结构与算法笔记(青岛大学王卓老师视频)
写在前面的话: 因为在学习数据结构之前,学习过一年的算法,所以有一些基础,一些我觉得 没必要的代码或知识就没写上,记得多是一些知识点,写的可能对于别人来说 很难接受,望谅解.我学习算法是在Acwing ...
- codeup墓地目录(算法笔记习题刷题笔记)
在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门模拟->简单模拟 ...
- 算法笔记知识点整理大全
每次刷题都觉得自己吃了知识点不全,基础不牢固的亏,刷题的时候目标也不明确,于是看完了算法笔记并把知识点归纳了一下,当然直接看书会更加详细,这个归纳只是学习时加深印象以及方便自己之后回顾而已:之后刷题大 ...
- 算法笔记学习PAT甲级解题记录
算法笔记学习记录 2019.06.26 float&&double 推荐全部使用double,注意区分scanf("%lf",&double1);与prin ...
- 考研算法笔记(排序)
考纲 (只考虑内部排序) 1插入排序(直插(稳),希尔) 2交换排序(冒泡(稳),快排) 3选择排序(简选,堆排) 4归并排序(稳) 5基数排序(稳) 6算法笔记 对任意n个关键字排序的比较次数至少为 ...
- JS数据结构与算法 笔记
JS数据结构与算法笔记 前言:不定时更新说明 1. 栈(Stack) 1.1 基于数组实现栈 1.2 基于对象实现栈 1.3 基于链表实现栈 1.4 栈的简单应用 1.4.1 字符串中的括号匹配问题 ...
- 《算法笔记》——笔记
算法笔记 胡凡 曾磊 主编 机械工业出版社 文章目录 算法笔记 C/C++快速入门 提醒 memset sscanf与sprintf 引用 浮点数的比较 圆周率 复杂度 黑盒测试 入门篇(1)--入门 ...
最新文章
- 详解深度学习中的Normalization,不只是BN(2)
- Servlet 流程控制
- [转]关于凸优化的一些简单概念
- Python高能小技巧:用海象操作符减少重复代码
- 【学术研究】保持高效论文写作的10个原则!
- 程序员修炼之道(一)
- 小米笔记本pro lol测试软件,小米笔记本Pro 15增强版游戏性能测评
- 文档管理系统mindoc安装
- 人工智能和溯因推理 AI的历史一直被演绎和归纳所主导
- setup maven plugin connection
- kali里的powersploit、evasion、weevely等工具的杂项记录
- java人机猜拳模块流程图_基于java实现人机猜拳游戏
- css前端日记之盒子模型-----一起去未来
- 三万字总结╰(*°▽°*)╯ 计算机网络 知识点汇总
- 实数截断式保留两位小数
- 虚拟机 安装 CUDA 可行性说明
- 2020年笔记本电脑计算机专业,适合女生用的笔记本电脑排名2020
- 校招----shein一面面经
- 电脑重装系统Win10“initpki.dll”加载失败怎么办?
- 快讯 | 第80届金球奖揭晓
热门文章
- 【SSL】【Apache】 配置 https/ssl
- echarts如何获取后端的值_Echarts 获取后台数据 使用后台数据展示 柱形图
- 商品审核网页界面_商品模块数据库表解析(二)
- 农村信用社计算机基础知识,2014年云南省农村信用社考试计算机基础知识练习题...
- keras冻结_[开发技巧]·keras如何冻结网络层
- tcp接口测试工具_你不了解的,完整“接口测试”与服务虚拟化
- 循环结果添加到集合_Java Note-数据结构(4)集合
- shell+mysql获取数据库名_shell操作mysql数据库
- arcgis 圈选获取图层下点位_ArcGIS小技巧——提取面要素的质心点
- anaconda 命令