堆排其实就是选择排序,只不过用了完全二叉树特性。

      堆排思想 : 利用完全二叉树特性建堆和重复选择调整来得到有序数组

      完全二叉树有什么特性呢? 节点左对齐 ---> 层序遍历不会出现空,可以用数组表达(访问效率高)

      那么可以将它映射到数组上,并且遵循一个规律: 设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 图解堆排的更多相关文章

  1. DS 图解快排

    快速排序是交换排序,是冒泡排序的改进版. 快排过程: 1.选定一个分界值     2.分成三个部分(小于分界部分,分界值,大于分界值部分)                       3.对于分开的两 ...

  2. DS 图解归并排序

    经典排序三剑客: 归并,堆排,快排. 今天,图解归并,一步步带你手撕代码~ 归并排序,是采用"分而治之"思想的一个典型应用. 分治法精髓: 1.分 --- 将问题分解成若干个规模更 ...

  3. 数组第K小数问题 及其对于 快排和堆排 的相关优化比较

    题目描述 给定一个整数数组a[0,...,n-1],求数组中第k小数 输入描述 首先输入数组长度n和k,其中1<=n<=5000, 1<=k<=n 然后输出n个整形元素,每个数 ...

  4. 【Algorithm】堆排,C++实现

    对一个数组中的元素按照顺序构建二叉树,就形成了一个(二叉)堆.(二叉树是虚拟的,并不是真的建立二叉树) 表示堆的数组A有两个重要属性:A.heapSize,表示堆里面有多少元素,数组里有多少元素在堆里 ...

  5. 造轮子-Java泛型堆排

    个人博客地址:http://kyle.org.cn/2018/03/13/heapsort/ Java实现泛型堆排算法,用于N个对象中选择最大或者最小的前M个,其中M<=N 类似于Mysql中o ...

  6. P1177 【模板】快速排序(学完归并和堆排之后的二更)

    P1177 [模板]快速排序 不用说,连题目上都标了是一道模板,那今天就来对能用到的许多排序方式进行一个总结: 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理 ...

  7. 图解堆算法、链表、栈与队列(Mark)

    原文地址: 图解堆算法.链表.栈与队列(多图预警) 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间 ...

  8. 排序算法C语言实现——冒泡、快排、堆排对比

    对冒泡.快排.堆排这3个算法做了验证,结果分析如下: 一.结果分析 时间消耗:快排 < 堆排 < 冒泡. 空间消耗:冒泡O(1) = 堆排O(1) < 快排O(logn)~O(n) ...

  9. python 快排,堆排,归并

    #归并排序 def mergeSort(a,L,R) :     if(L>=R) :         return     mid=((L+R)>>1)     mergeSort ...

随机推荐

  1. 再见Spring Boot 1.x

    记得很早很早之前有过一次面试,面试前端说自己喜欢JavaScript,然后面试官问,你知道当前JavaScript最新标准和规范吗?我无言以对,因为平时没有关注认真对待这些信息,然后就没有然后了. 或 ...

  2. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

  3. R 指定安装镜像的方法

    方法一 options(repos=structure(c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))) install ...

  4. Centos7 U盘安装&命令大全

    软件下载 1.centos下载,下载地址https://www.centos.org/download/ 我选择的镜像是:CentOS-7-x86_64-DVD-1804.iso 2.UltraISO ...

  5. java 多页pdf转化为多张图片

    相关jar包: <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian ...

  6. Unity2D音游案例-节奏大师教程+源码+素材

    Unity2D音游案例-节奏大师(Unity2017.2 ,基于Koreographer),本案例涉及到一些音乐音频音波的一点点内容. 首先,我们会把音游的核心功能实现,之后几个重要内容会出给思路并带 ...

  7. java SDK服务端推送 --极光推送(JPush)

    网址:https://blog.csdn.net/duyusean/article/details/86581475 消息推送在APP应用中越来越普遍,来记录一下项目中用到的一种推送方式,对于Andr ...

  8. Linux下如何测试网速

    本文链接:https://blog.csdn.net/Beyond_F4/article/details/80497118在Linux下如何测量下载和上传的速度? 这里用到一个Python工具spee ...

  9. 【laravel5.5+Passport】laravel5的前后端分离之Passport设计

    项目中使用到了laravel5的passport组件,进行前后端分离的 api认证部分: 前后端分离的api认证,我们用的是: [密码授权令牌],需要用户登录->指定client_id/clie ...

  10. C# RSA 无 长度限制 加密解密 示例

    RSA 是一种非对称加密算法.由于算法特性,加密和解密过程用不同密钥,即公钥和私钥,而被广泛应用于数字证书的安全管理. 在具体应用中,公钥用加密而私钥用于解密,或 私钥用于数字签名而公钥用于签名验证. ...