堆排序算法(图解详细流程)

article/2025/10/29 22:35:04

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 堆排序基本介绍
  • 大顶堆举例说明
  • 小顶堆举例说明
  • 堆排序的基本思想
  • 堆排序步骤图解说明
  • 堆排序的基本思路总结


堆排序基本介绍

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

  2. 堆是具有以下性质的完全二叉树,每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆,注意:没有要求节点的左孩子的值和右孩子的值的大小关系。

  3. 每个结点的值都小于或等于其左右孩子节点的值,称为小顶堆

大顶堆举例说明

在这里插入图片描述
我们对堆中的节点按层进行编号,映射到数组中就是下面这个样子:
在这里插入图片描述
大顶堆特点:arr[i]>=arr[2i+1]&&arr[i]>=arr[2i+2]

小顶堆举例说明

在这里插入图片描述
小顶堆特点:arr[i]<=arr[2i+1]&&arr[i]<=arr[2i+2]//i对应第几个节点,i从0开始标号
一般升序采用大顶堆,降序采用小顶堆

堆排序的基本思想

  1. 将待排序序列构造成一个大顶堆

  2. 此时整个序列的最大值就是顶堆的根节点

  3. 将其与末尾元素进行交换,此时末尾就为最大值

  4. 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

    可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了

堆排序步骤图解说明

要求:有一个数组{4,6,8,5,9},要求使用堆排序法,将数组升序排序
一、
1.假设给定无序序列结构如下
在这里插入图片描述
2.此时我们从最后一个非叶子节点开始(叶节点自然不用调整,第一个非叶子节点arr.length/2-1=5/2-1=1,也就是下面的节点),从左至右,从下至上进行调整,观察6的两个子节点,从右至左,9大于6就和6互换
在这里插入图片描述
3.找到第二个非叶子节点4,由于[4,9,8]中9元素最大,4和9交换
在这里插入图片描述
4.此时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6
在这里插入图片描述
5.此时我们就将一个无序序列构造成了一个大顶堆
二、
将堆顶元素与末尾元素进行交换,使末尾元素最大,然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素,如此反复进行交换,重建,交换

1.将堆顶元素9和末尾元素4进行交换
在这里插入图片描述
2.重新调整结构,使其继续满足堆定义
在这里插入图片描述
3.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8
在这里插入图片描述
4.后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
在这里插入图片描述

堆排序的基本思路总结

  1. 将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
  2. 将堆顶元素与末尾元素交换,将最大元素“沉”到数组末端
  3. 重新调整结构使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
    private static void heapSort(int[] arr) {int temp = 0;//堆排序for(int i = arr.length/2-1;i>=0;i--){adjustHeap(arr,i,arr.length);}for (int j=arr.length-1;j>0;j--){temp = arr[j];arr[j] = arr[0];arr[0] = temp;adjustHeap(arr,0,j);}System.out.println("数组="+Arrays.toString(arr));}/*** 将以i对应的非叶子节点的树调整成一个大顶堆* 举例 int[] arr = {4,6,8,5,9};=>i=1 =>{4,9,8,5,6} => i=0 =>{9,6,8,5,4}* @param arr* @param i 表示非叶子节点在数组中的索引* @param length 对多少个元素进行调整*/public static void adjustHeap(int[] arr,int i,int length){//a[i]>a[2i+1]&&a[i]>a[2i+2]int temp = arr[i];for (int k=i*2+1;k<length;k=k*2+1){//先比较左子节点和右子节点的大小,最大的那个和temp进行交换if(k+1<length && arr[k]<arr[k+1]){k++;//k指向右子节点}//如果非子节点的值小于左子节点和右子节点的值if(arr[k]>temp){//temp和arr[k]进行交换arr[i] = arr[k];i=k;//继续循环比较,假设k是左子节点,k+1是右子节点,然后引出公式}else{break;}}//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶上(局部)arr[i]=temp;}

http://chatgpt.dhexx.cn/article/dsVodMuL.shtml

相关文章

堆排序详细图解(通俗易懂)

什么是堆 堆是一种叫做完全二叉树的数据结构&#xff0c;可以分为大根堆&#xff0c;小根堆&#xff0c;而堆排序就是基于这种结构而产生的一种程序算法。 堆的分类 大根堆:每个节点的值都大于或者等于他的左右孩子节点的值 小根堆:每个结点的值都小于或等于其左孩子和右孩子…

PreferenceActivity(二)

看到很多书中都没有对PreferenceActivity做介绍&#xff0c;而我正好又在项目中用到&#xff0c;所以就把自己的使用的在这总结一下&#xff0c;也方便日后查找。 PerferenceActivity是什么&#xff0c;看下面的截图&#xff1a; Android系统截图&#xff08;左&#xff09; …

android设置页面之PreferenceActivity及Preference

离上篇博客刚好一周&#xff0c;希望后面会记录更多的内容&#xff0c;也算自己的Android笔记吧。 本篇主要记录一般的android设置页面PreferenceActivity的使用以及与之剪不断&#xff0c;理还乱的Preference。 &#xff08;一&#xff09;如何使用 Android系统自带的设置应用…

android中PreferencesActivity的使用(一)

在使用android手机的时候&#xff0c;尤其是在操作软件设置时&#xff0c;我们经常见到这样的界面&#xff1a; 这是怎么来实现的的呢&#xff1f;其实android已经提供了相应的类和方法&#xff0c;当进行简单数据存储时&#xff08;比如&#xff1a;软件配置参数&#xff09;a…

PreferenceActivity用法简介(二)

本测试主要是为了测试PreferenceActivity的使用&#xff0c;其中设置了播放背景音乐和开启wifi的设置&#xff0c;也就是本文要讲的 PreferenceActivity。 Android提供了放摆放的工具来定义所有的程序的首选项&#xff0c;并支持既不不许要编写代码的情况写显示这些首选项。可…

Android之PreferenceActivity

看到很多书中都没有对PreferenceActivity做介绍&#xff0c;而我在看Android Samples时无意中看见了&#xff0c;所以就稍微总结一下&#xff0c;也方便日后查找。 PerferenceActivity是什么&#xff0c;看下面的截图&#xff1a; 好了&#xff0c;我们看到Android系统本身就大…

Android PreferenceActivity使用

PreferenceActivity继承了ListActivity&#xff0c;定义Activity继承PreferenceActivity。在res目录下新建一个xml文件夹&#xff0c;接着在这个文件夹下新建一个取名为preferences.xml的File文件&#xff0c;xml中可以使用的标签(Tag)可以分为两类&#xff0c;一类是管理布局的…

PreferenceActivity定制

android很多设置界面都会使用PreferenceActivity来实现&#xff0c;但那个界面比较丑陋&#xff0c;显示开发总是满足不了要求。 可以自己实现一个&#xff0c;但是那样又会使Activity中的逻辑代码和xml布局文件过于复杂&#xff0c;远远不及PreferenceActivity来的方便快捷。…

PreferenceActivity、PreferenceFragment使用

目录 目录前言PreferenceActivity preferences_scenario_1xmlPreference Activity演示 PreferenceFragment xml布局文件Preference FragmentPreference Activity管理Fragment 适配 前言 转来转去又回到了Android&#xff0c;闲话少说&#xff0c;这里是参考Android原生的Setti…

Android PreferenceActivity的介绍

转载&#xff1a;http://blog.chinaunix.net/uid-24666775-id-351136.html 在Android中的APIdemos是中经常遇到过继承于PreferenceActivity这个类&#xff0c;紧接着就是addPreferencesFromResource(R.xml.*******);&#xff08;附&#xff1a;这个******就是一个XML文件&#…

Android开发--详解SharedPreference/PreferenceActivity

我们经常看到应用程序的设置页面&#xff0c;一般用到设置页面时&#xff0c;我们会继承自PreferenceActivity&#xff0c;它实现了SharedPreference&#xff0c;并生成相应的XML文件自动保存用户的设置&#xff0c;在设置页面中&#xff0c;每一个列表项都是一个Preference&am…

Android之PreferenceActivity 详解

看到很多书中都没有对PreferenceActivity做介绍&#xff0c;而我正好又在项目中用到&#xff0c;所以就把自己的使用的在这总结一下&#xff0c;也方便日后查找。 PerferenceActivity是什么&#xff0c;看下面的截图&#xff1a; Android系统截图&#xff08;左&#xff09; …

android的PreferenceActivity

前言 这段时间在研究android平台上的开源项目——StandupTimer&#xff0c;这是由jwood所设计的一个较为简单android应用&#xff0c;用于控制会议时间&#xff0c;类似秒表倒计时。 PreferenceActivity PreferenceActivity是android提供的对系统信息和配置进行自动保存的Activ…

用StopWatch统计耗时,比System.currentTimeMillis好用

平时项目中统计耗时都用System.currentTimeMillis&#xff0c;最近看到一个spring-StopWatch统计耗时&#xff0c;其用法简单明了&#xff0c;比传统统计耗时方法好用。 StopWatch 的内部是通过 System.nanoTime() 来计时的&#xff0c;本质和 System.currentTimeMillis() 差别…

并发慎用——System.currentTimeMillis()

好记忆不如烂笔头&#xff0c;能记下点东西&#xff0c;就记下点&#xff0c;有时间拿出来看看&#xff0c;也会发觉不一样的感受. System.currentTimeMillis()是极其常用的基础Java API&#xff0c;广泛地用来获取时间戳或测量代码执行时长等&#xff0c;在我们的印象中应该快…

System.currentTimeMillis()的性能问题以及解决方法

System.currentTimeMillis()是极其常用的基础Java API&#xff0c;广泛地用来获取时间戳或测量代码执行时长等&#xff0c;在我们的印象中应该快如闪电。但实际上在并发调用或者特别频繁调用它的情况下&#xff08;比如一个业务繁忙的接口&#xff0c;或者吞吐量大的需要取得时…

统计代码执行时间时,System.currentTimeMillis()与System.nanoTime()哪个更适合?

目录 1.nanoTime是什么&#xff1f; 2.currentTimeMillis是什么&#xff1f; 3.nanoTime与currentTimeMillis在JDK中阐述 4.nanoTime与currentTimeMillis使用对比 5.深究从OpenJDK源代码、glibc&#xff0c;一直到Linux内核 6.总结 1.nanoTime是什么&#xff1f; ns&…

System.currentTimeMillis的性能如何

一、背景 撸代码时发现System.currentTimeMillis的调用都被封装成了cache类型&#xff0c;代码如下: 那么System.currentTimeMillis真的有这么这么差吗&#xff0c;如果差的话又是什么原因造成的&#xff1f;什么情况下可以直接调用原生方法&#xff0c;什么情况下需要使用缓存…

别再用 System.currentTimeMillis 统计耗时了,太 Low,试试 Spring Boot 源码在用的 StopWatch吧,够优雅

大家好&#xff0c;我是二哥呀&#xff01; 昨天&#xff0c;一位球友问我能不能给他解释一下 SpringBootApplication 注解是什么意思&#xff0c;还有 Spring Boot 的运行原理&#xff0c;于是我就带着他扒拉了一下这个注解的源码&#xff0c;还有 SpringApplication 类的 ru…

System.currentTimeMillis的性能,真有如此不堪吗?

# 疑惑&#xff0c;System.currentTimeMillis真有性能问题&#xff1f; 最近我在研究一款中间件的源代码时&#xff0c;发现它获取当前时间不是通过System.currentTimeMillis&#xff0c;而是通过自定义的System.currentTimeMillis的缓存类&#xff08;见下方&#xff09;&…