堆排序

同步微信公众号乐享Coding,欢迎你的关注!

介绍:利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它是不稳定排序。

对于堆排序,难点在于二叉树的顺序数组储存到大顶堆(小顶堆)的转换。从数据存储来看,数组存储方式树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组。我习惯于不空谈理论,拿实例讲解,以下将针对数组arr[1,2,5,4,3,7]进行大顶堆的数据结构转换。

如图:

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

代码实现思路:

步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。

图解大顶堆详细思路:

  • 我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的索引为2的结点),从右至左从下至上进行调整。

  • 由于[5,7]中7元素最大,5和7交换。

  • 最后一个非叶子结点索引减1,找到第二个非叶结点(索引1),由于[4,3,2]中4元素最大,2和4交换。

  • 非叶子结点索引减1,找到第三个非叶结点(索引0),由于[4,1,7]中7元素最大,1和7交换。

  • 这时,交换导致了子根[1,5]结构混乱,继续调整,[1,5]中5最大,交换1和5。

  • 此时,我们就将一个无序序列构造成了一个大顶堆。

步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

最后,就实现了堆排序。

文章末尾将代码附上,如有不清楚的地方,可以Debug加深下理解!

   public static void heapSort(int[] arr) {//1.构建大顶堆for (int i = arr.length / 2 - 1; i >= 0; i--) {//从第一个非叶子结点从下至上,从右至左调整结构adjustHeap(arr, i, arr.length);}//然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。//2.调整堆结构+交换堆顶元素与末尾元素for (int j = arr.length - 1; j > 0; j--) {swap(arr, 0, j);//将堆顶元素与末尾元素进行交换adjustHeap(arr, 0, j);//重新对堆进行调整}}/*** 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上, 也就是说只调用一次,并没有得到大顶堆)* 就是将arr[i] 的值放到本次 调整过程中适当的位置。* @param arr    : 数组* @param i      : 非叶子节点的索引* @param length : 对多少个元素进行调整,这个length是逐渐减少的..*/public static void adjustHeap(int[] arr, int i, int length) {int temp = arr[i];//先取出当前元素ifor (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//从i结点的左子结点开始,也就是2*i+1处开始if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子结点小于右子结点,k指向右子结点k++;}if (arr[k] > temp) {//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)arr[i] = arr[k];//把较大的值,赋给当前节点i = k;//i 指向k,继续循环比较} else {break;}}arr[i] = temp;//将temp值放到最终的位置}public static void swap(int[] arr, int a, int b) {int temp = arr[a];arr[a] = arr[b];arr[b] = temp;}

最详细的堆排序---排序算法,思路清晰动图讲解,五分钟搞懂!相关推荐

  1. 一文读懂Python版的十大经典排序算法(附动图演示)

    来源:大数据DT 本文约5200字,建议阅读10分钟 排序算法是<数据结构与算法>中最基本的算法之一.本文介绍10种常见的内部排序算法,及如何用Python实现. 排序算法可以分为内部排序 ...

  2. C语言八大排序算法,附动图和详细代码解释!

    文章来源:电子工程专辑.C语言与程序设计.竹雨听闲 一.前言 如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的. 二. ...

  3. 硬核!C语言八大排序算法,附动图和详细代码解释!

    来源 :C语言与程序设计.竹雨听闲等 一 前言 如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的. 二 八大排序算法 ...

  4. 排序算法——冒泡排序原理动图详解及实现

    主要涉及的是内部排序  交换排序   => 冒泡排序   快速排序  选择排序   直接选择排序   堆排序  插入排序   直接插入排序   希尔排序  归并排序 冒泡排序 1. 简介 冒泡排 ...

  5. java快速排序直观演示代码,排序算法总结(含动图演示和Java代码实现)

    本文将围绕冒泡排序.桶排序.计数排序.堆排序.插入排序.并归排序.快速排序和选择排序,按照描述.时间复杂度(最坏情况).动态图展示和代码实现来讲解.本文默认排序为从小到大. 本文相关代码已上传至git ...

  6. 【排序算法】冒泡排序(动图演示) - 保姆级详解

    冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来. 算法步骤 比较相邻的元素.如果第一个比第二个大,就交换 ...

  7. 排序算法-冒泡排序(可视化动图)

    冒泡排序 冒泡排序(Bubble Sort) 最为简单的一种排序,通过重复走完数组的所有元素,通过打擂台的方式两个两个比较,直到没有数可以交换的时候结束这个数,再到下个数,直到整个数组排好顺序.因一个 ...

  8. sha256算法_叶胜超:一分钟搞懂哈希以及哈希算法!(15)

    哈希算法 什么是哈希? 哈希的英文:Hash,也可翻译成"散列",也是一种哈希算法的最小单位H,其它单位还有KMGTPE共6个,胜超在前文也讲过,可以用谐音"昆明哥,突破 ...

  9. 五分钟搞懂游戏开发中的抗锯齿算法

    常见抗锯齿算法总结 锯齿由来 抗锯齿算法 SSAA MSAA CSAA FSAA TAA 锯齿由来 场景的定义在三维空间中是连续的,而最终显示的像素则是一个离散的二维数组,这是计算机屏幕产生锯齿的原因 ...

最新文章

  1. 有没有适合部署在局域网的团队协作平台?
  2. 关于字符串计算size的方法比较
  3. ajax nginx 转发 sessionid_Nginx+Apache实现动静分离 - 孙天飞
  4. 时频分析:短时傅立叶变换实现(4)
  5. 以太坊地址和公钥_以太坊交易签名解析源码解读
  6. iphone查看删除的短信_iPhone12发布!刚买的苹果手机短信全部消失了怎么办?
  7. URL(待整合到HTTP书中哦)
  8. 审题解题没思路?算法大赛出题方为你指点迷津!
  9. 进行有效客户细分的八个步骤
  10. Metatable让我从心认知了Lua(相知篇)
  11. php家族族谱代码,家族族谱系统设计.doc
  12. 运维团队(OPS)与技术团队有效沟通配合探讨
  13. 网上查信用报告,什么是数字证书验证?
  14. spring跨重定向传递数据
  15. 牛逼的Python库MoviePy!利用Python自动剪辑tiktok视频!
  16. 成组链接法 恩赐解脱
  17. 原来这才是高铁霸座男的真实目的!
  18. linux centos 解压 tar.bz2文件
  19. 苏宁智慧零售2018: 大象轻舞,一动千钧 | 一点财经
  20. Java bho插件_VC++开发BHO插件——定制你的浏览器 --------- 转

热门文章

  1. DNS Wildcard(DNS泛域名)
  2. 真的能从脑电信号识别出我的情绪吗?
  3. 工厂模式---简单工厂、工厂方法代码讲解
  4. Java script事件详解
  5. 返回空 Buckets
  6. CSS学习笔记(3)【CSS元素显示模式以及背景设置】
  7. jQuery中的hover()方法
  8. 和女友xx完后她说:“你是我的。”
  9. mtu测试软件 win7,告诉你mtu值怎么设置才能网速最好!
  10. 一般引起Cookie丢失的原因