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

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

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

      那么可以将它映射到数组上,并且遵循一个规律: 设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. Python-内存泄漏 持续增长 检查点

    仅个人目前遇见的内存问题, 可能不适用所有问题 一下只是简单的实例代码, 可能跑不起来, 只是看看 可变变量参数 小例子: def foo(a, b=[]): b.append(a) print b ...

  2. ACM数据结构-单调栈、队列

    1.最大数 代码: #include <stdio.h> #include <memory.h> #include <math.h> #include <st ...

  3. luogu P1550 [USACO08OCT]打井Watering Hole

    题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pastur ...

  4. 洛谷P4735题解

    若想要深入学习可持久化0-1Trie树,传送门. Description: 给定数列 \(\{a_n\}\) ,支持两种操作: 在数列尾添加一个数 \(x\) ,数列长度变成 \(n+1\) ; 给定 ...

  5. shell 输出文件各行的长度

    test.sh #!/bin/bash string="hello,shell,split,test" array=(${string//,/ }) for var in ${ar ...

  6. nginx配置自签名https

    nginx配置https是需要CA颁发证书的,为了测试方便,我们可以使用自签名证书 1.如何生成自签名证书 1.1:我们需要为服务端和客户端准备私钥和公钥: //生成服务器端私钥 openssl ge ...

  7. Features Track[STL map]

    目录 题目地址 题干 代码和解释 参考 题目地址 Features Track(ACM-ICPC 2018 徐州赛区网络预赛 ) 题干 代码和解释 题意:一个动画有许多 n 帧,每帧有 k 个点,点的 ...

  8. mysql一对多表结构,查询一的信息的同时统计多的数量

    res_resource_catalog表对于res_info_item表是一对多, 查询res_resource_catalog信息的同时,统计res_info_item中该条res_resourc ...

  9. Java NIO Buffer中各种状态属性的含义

    关于NIO Buffer中的3个重要状态属性的含义: postion, limit与capacity. public class NioTest { public static void main(S ...

  10. flutter 打包apk之后,安装在手机上无法访问网络解决方法

    </application> <uses-permission android:name="android.permission.READ_PHONE_STATE" ...