DS 图解堆排
堆排其实就是选择排序,只不过用了完全二叉树特性。
堆排思想 : 利用完全二叉树特性建堆和重复选择调整来得到有序数组。
完全二叉树有什么特性呢? 节点左对齐 ---> 层序遍历不会出现空,可以用数组表达(访问效率高)
那么可以将它映射到数组上,并且遵循一个规律: 设i为当前节点索引,
i->left = 2*i+1 i->right = 2*i+2 可得-->
i = (i->left-1)/2 = (i->right-2)/2 = (i->left-2 +1)/2 = (i->left-2)/2 + 1/2(计算机整除为0) = (i->child-1)/2
堆排序种类:
大根堆 : parent > left && right ---> 升序
小根堆 : parent < left && right ---> 降序
堆排序最经典的问题就是topK问题。
堆排过程(假如要降序) :
1. 建小堆
建小堆过程: 1.找到最后一个非叶子节点(叶子节点不用调整,因为向下调整前提是有孩子),进行向下调整
2.依次向前将所有非叶子节点调整完,小堆也就构建好了
1.选最后一个非叶子节点 3,向下调整
2.继续找倒数第二个非叶子节点向下调整,重复直到全部非叶子节点调整完成
此时,小堆建立完成,堆顶为数组中最小值。
2. 向下调整 `
向下调整过程: 1.小堆顶部是最小值,将其与最后一个节点交换,最小值固定
2.将根节点与最小的孩子节点比较,若是不是最小值则交换,继续调整递归比较,找到合适的位置,再次形成小堆
3.循环1,2步骤直到所有值固定
1.交换1和3,固定1
2.向下调整形成小堆
3.重复1,2步骤直到固定所有值
C/C++代码demo:
- #include<algorithm>
- //向下调整
- //和孩子比较,小了退出,大了交换
- void AdjustDown(int* arr,int n,int root)
- {
- int parent = root;
- int child = root* + ;
- //交换边界: 交换到最后的位置了
- while(child<n)
- {
- //找最小的孩子
- if(child+<n && arr[child]>arr[child+])
- {
- ++child;
- }
- //大了交换,并更新父子节点
- if(arr[parent]>arr[child])
- {
- swap(arr[parent], arr[child]);
- parent = child;
- child = *parent+;
- }
- //小了退出
- else
- {
- break;
- }
- }
- }
- //堆排序 --- 降序,造小堆
- // 下标获取方法:
- // i->left = i*2 + 1 i->right = i*2 + 2
- // i = (i->child-1) * 2
- void HeapSort(int* arr,int n)
- {
- //1.建堆 --- 从最后一个非叶子节点依次向下调整
- //最后一个非叶子节点确定方法: n-1的父亲,因为左对齐,所以此位置前面都有孩子
- for(int i=(n-)/;i>=;--i)
- AdjustDown(arr,n,i);
- //2.向下调整 --- 重复交换,固定,向下调整直到全部固定
- for(int end=n-;i>;--i){
- swap(arr[],arr[end])
- AdjustDown(arr,n-,i);
- }
- }
DS 图解堆排的更多相关文章
- DS 图解快排
快速排序是交换排序,是冒泡排序的改进版. 快排过程: 1.选定一个分界值 2.分成三个部分(小于分界部分,分界值,大于分界值部分) 3.对于分开的两 ...
- DS 图解归并排序
经典排序三剑客: 归并,堆排,快排. 今天,图解归并,一步步带你手撕代码~ 归并排序,是采用"分而治之"思想的一个典型应用. 分治法精髓: 1.分 --- 将问题分解成若干个规模更 ...
- 数组第K小数问题 及其对于 快排和堆排 的相关优化比较
题目描述 给定一个整数数组a[0,...,n-1],求数组中第k小数 输入描述 首先输入数组长度n和k,其中1<=n<=5000, 1<=k<=n 然后输出n个整形元素,每个数 ...
- 【Algorithm】堆排,C++实现
对一个数组中的元素按照顺序构建二叉树,就形成了一个(二叉)堆.(二叉树是虚拟的,并不是真的建立二叉树) 表示堆的数组A有两个重要属性:A.heapSize,表示堆里面有多少元素,数组里有多少元素在堆里 ...
- 造轮子-Java泛型堆排
个人博客地址:http://kyle.org.cn/2018/03/13/heapsort/ Java实现泛型堆排算法,用于N个对象中选择最大或者最小的前M个,其中M<=N 类似于Mysql中o ...
- P1177 【模板】快速排序(学完归并和堆排之后的二更)
P1177 [模板]快速排序 不用说,连题目上都标了是一道模板,那今天就来对能用到的许多排序方式进行一个总结: 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理 ...
- 图解堆算法、链表、栈与队列(Mark)
原文地址: 图解堆算法.链表.栈与队列(多图预警) 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间 ...
- 排序算法C语言实现——冒泡、快排、堆排对比
对冒泡.快排.堆排这3个算法做了验证,结果分析如下: 一.结果分析 时间消耗:快排 < 堆排 < 冒泡. 空间消耗:冒泡O(1) = 堆排O(1) < 快排O(logn)~O(n) ...
- python 快排,堆排,归并
#归并排序 def mergeSort(a,L,R) : if(L>=R) : return mid=((L+R)>>1) mergeSort ...
随机推荐
- SQL进阶-索引设置&sql优化
一.索引设置 1.索引的设置原则 经常出现在WHERE条件.关联条件中的字段作为索引字段: 在满足查询需求的前提下,应尽可能少的创建索引:(对于一个组合索引,可以满足以组合索引左边的一部分字段的查询需 ...
- mysql初始
数据(data) : -描述事物的符号记录称为数据,符号既可以是数据,文字,图片,声音,语言等,符号都可以经过数字化后存入计算机中 - 计算机中描述一个事物,就需要抽取这一事物的典型特征,组成一条记录 ...
- ES6基础-变量的解构赋值
作者 | Jeskson 来源 | 达达前端小酒馆 解构赋值: 数组的解构赋值,对象的解构赋值,字符串的解构赋值,数值与布尔值的解构赋值,函数参数的解构赋值. 开发环境准备: 编辑器,VS Code, ...
- [Beta阶段]第七次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第七次Scrum Meeting 基本信息 名称 时间 地点 时长 第七次Scrum Meeting 19/05/13 大运村寝室6楼 35min ...
- Linux下的sleep()和sched_yield()(转)
阿里四面被问到了这个问题,一脸懵逼,下来也没找到什么阐述这个的文章,就自己查man来对比总结一下吧: sched_yield()的man手册描述如下: DESCRIPTION sched_ ...
- python windows下安装pip及rarfile
python之所以被广泛使用,倒不见得是本身语法简单,而是而nodejs/javascript一样把三方库的依赖管理简化了,而不用和java一样非得通过maven管理,而且还得打包后在classpat ...
- java字符串格式化性能对比String.format/StringBuilder/+拼接
String.format由于每次都有生成一个Formatter对象,因此速度会比较慢,在大数据量需要格式化处理的时候,避免使用String.format进行格式化,相反使用StringUtils.l ...
- python开发--Python实现延时操作的几种方式
1. time.sleep 2. sched.scheduler 3. threading.Timer 4. 借助其他程序 celery redis延时队列 在日常的开发中,往往会遇到这样的需求,需要 ...
- 查看apache httpd server中加载了哪些模块
说明: 有的时候,需要查看当前apache中都加载了哪些模块,通过以下命令进行查看 [root@hadoop1 httpd-]# bin/apachectl -t -D DUMP_MODULES Lo ...
- Java8相关底层
Java8是往并行方向走的.由面向对象到函数式编程. 在支持函数式编程的同时还可以支持面向对象的开发. 在JDK1.8里面,接口里面可以有实现方法的!默认方法,default.实现这个接口. 接口里面 ...