数据结构——堆排序(算法)

article/2025/10/29 18:27:03

基本介绍

  • 1)、堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最好、最坏、平均时间复杂度均为O(nlogn),它也是不稳定排序。
  • 2)、堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆,注意:没有要求节点的左孩子的值和右孩子的值的大小关系。
  • 3)、每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆
  • 4)、大堆顶举例说明,堆数据都是以顺序存储二叉树的形式存储到数组中。
    在这里插入图片描述
  • 5)、小堆顶距离说明
    在这里插入图片描述
  • 6)、一般升序用大顶堆,降序用小顶堆

基本思想:

  • 1)、将待排序序列构造成一个大顶堆或小顶堆;
  • 2)、此时,整个序列的最大值或最小值就是堆顶的根节点;
  • 3)、将其与末尾元素进行交换,此时末尾就为最大值或最小值;
  • 4)、然后将剩余的 n-1 个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
    可以看到在构建大堆顶的过程中,元素的个数逐渐减少,最后就得到一个有序序列了。

举例:

  • 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序用大顶堆,降序用小顶堆)
  • 1)、原始数组{4,6,8,5,9}
    在这里插入图片描述
    2)、此时我们从最后一个非叶子节点开始(叶节点自然不用调整,第一个非叶子节点 arr.length/2 -1 =5/2 -1 = 1,也就是下面的6节点),从左至右,从下至上进行调整。
    在这里插入图片描述
  • 3)、找到第二个非叶子节点4,由于【4,9,8】中的9元素最大,4和9 交换
    在这里插入图片描述
    4)、这时,交换导致了根【4,5,6】结构混乱,继续调整,6最大,交换4和6
    在这里插入图片描述
  • 此时,我们就将一个无序序列构造成了一个大顶堆。
  • 5)、将堆顶元素和末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素和末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。
  • 6)、交换堆顶元素和末尾元素的值
    在这里插入图片描述
  • 7)、找到最后一个非叶子节点,【6,5】构造大顶堆,6大于5,不用交换
    在这里插入图片描述
  • 8)、找到非叶子节点【4,6,8】,构造大顶堆,8和4交换位置
    在这里插入图片描述
  • 9)、交换堆顶元素和末尾元素的值
    在这里插入图片描述
  • 10)、找到非叶子节点【5,6,4】,构造大顶堆,6和5交换位置
    在这里插入图片描述
  • 11)、交换堆顶元素和末尾元素的值
    在这里插入图片描述
  • 12)、找到非叶子节点【4,5】,构造大顶堆,4和5交换位置
    在这里插入图片描述
  • 13)、交换堆顶元素和末尾元素的值
    在这里插入图片描述
  • 14)、最后得到一个有序序列{4,5,6,8,9}

示例代码

public class HeapSortDemo {public static void main(String[] args) {int[] arr = {4, 6, 8, 5, 9};/*** 1)、将无序数组构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;*/int k = 1;for (int i = arr.length / 2 - 1; i >= 0; i--) {adjustHeap(arr, i, arr.length);System.out.printf("%d = %s\n", k++, Arrays.toString(arr));}/*** 2)、将堆顶元素与末尾元素交换,将最大的元素“沉”到数组末端;* 3)、重新调整结构,使其满足堆定义,继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序*/int temp;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.printf("排序完成后的数组:%s\n", Arrays.toString(arr));}/*** 功能:将以i对应的非叶子节点的树调整为大顶堆(明白什么是顺序存储二叉树)* 举例:int[] arr = {4, 6, 8, 5, 9} => i=1 => adjustHeap => {4,9,8,5,6}* 如果我们再次调用adjustHeap 传入的是 i=0 => {9,6,8,5,4}** @param arr    待调整的数组* @param i      表示非叶子节点在数组中的索引* @param length 表示对多少个元素继续调整,length是在逐渐减少*/public static void adjustHeap(int[] arr, int i, int length) {/*取出当前元素的值,保存在临时变量*/int temp = arr[i];/*** k = i * 2 + 1: 表示以i为根节点的左子节点*/for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {/*** k+1: 表示与k节点相对的右子节点* arr[k] < arr[k + 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;}}/*当for循环结束后,我们已将以i为父节点的树的最大值放到了最顶(局部)*//*将temp的值放到调整后的位置*/arr[i] = temp;}
}

http://chatgpt.dhexx.cn/article/0asxAHfO.shtml

相关文章

C++:堆排序算法详解

图解排序算法(三)之堆排序 预备知识 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法&#xff0c;堆排序是一种选择排序&#xff0c;它的最坏&#xff0c;最好&#xff0c;平均时间复杂度均为O(nlogn)&#xff0c;它也是不稳定排序。首先简单了解下堆结构。 堆 堆是具有…

排序算法:堆排序算法实现及分析

堆排序介绍 堆排序&#xff08;Heap Sort&#xff09;就来利用堆&#xff08;假设利用大顶堆&#xff09;进行排序的方法。它的基本思想是&#xff0c;将待排序的序列构成一个大顶堆。此时&#xff0c;整个序列的最大值就是堆顶的根结点。将它移走&#xff08;其实就是将其与堆…

堆排序算法 总结

最近面试&#xff0c;老是被问到堆排序算法。 回答时老是感觉思路不清楚&#xff0c;现在总结一下&#xff0c;把思路弄清楚的。 1.堆排序是利用堆的特性对记录序列进行排序的一种排序方法。 好的那么堆得特性是什么呢&#xff1f; 堆得定义&#xff1a; 堆是满足下列性质的数…

Java实现堆排序算法

堆排序是计算机编程中一种流行且高效的排序算法。学习如何编写堆排序算法需要了解两种类型的数据结构-数组和树。 我们要排序的初始数字集存储在数组中&#xff0c;例如[10, 3, 76, 34, 23, 32]&#xff0c;排序后&#xff0c;我们得到一个排序后的数组[3,10,23,32,34,76] 堆排…

精通八大排序算法系列:二、堆排序算法

精通八大排序算法系列&#xff1a;二、堆排序算法 作者:July 、二零一一年二月二十日本文参考&#xff1a;Introduction To Algorithms&#xff0c;second edition。------------------- 此精通排序算法系列&#xff0c;前一节&#xff0c;已讲过了一、快速排序算法&#xff0c…

堆排序算法详解

一、堆排序算法原理和动态图解 将待排序的序列构造成一个大顶堆。此时&#xff0c;整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换&#xff0c;此时末尾元素就是最大值)&#xff0c;然后将剩余的n-1个序列重新构造成一个堆&#xff0c;这样就…

【堆排序算法】(C语言实现)

堆排序 一.堆排序1.堆的概念及性质1.1堆的概念1.2堆的性质 二.向下调整和向上调整两大算法1. 向下调整算法2.1 向下调整算法基本思路 2. 向上调整算法2.2 向上调整的基本思路 三.堆的实现&#xff08;小堆&#xff09;1.头文件包含2. 接口实现 四.任意树调整为堆&#xff08;小…

堆排序算法

堆排序 堆排序&#xff08;Heapsort&#xff09;是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构&#xff0c;并同时满足堆积的性质&#xff1a;即子结点的键值或索引总是小于&#xff08;或者大于&#xff09;它的父节点。 基本思想 利用大顶堆…

3.图解排序算法(三)之堆排序

作者&#xff1a; dreamcatcher-cx 出处&#xff1a; http://www.cnblogs.com/chengxiao/ 本文版权归作者和博客园共有&#xff0c;欢迎转载&#xff0c;但未经作者同意必须保留此段声明&#xff0c;且在页面明显位置给出原文链接。 原文链接&#xff1a;https://www.cnblogs.…

排序算法:堆排序

相关博客&#xff1a; 排序算法&#xff1a;冒泡排序、插入排序、选择排序、希尔排序 排序算法&#xff1a;归并排序、快速排序 排序算法&#xff1a;桶排序、计数排序、基数排序 排序算法&#xff1a;堆排序 十大排序算法小结 一、堆&#xff1a; 1、什么是堆&#xff1…

排序算法 —— 堆排序(图文超详细)

文章目录 堆排序1. 排序思路2. 如何建成大根堆2.1. 将待排序的数据看成一个完全二叉树。2.2. 建堆思想2.3. 建堆步骤2.3.1.先将最后一棵子树建成大根堆2.3.2.将其余子树建成大根堆2.3.3. 代码分析 3 如何实现堆排序3.1 排序思路3.2 代码实现的思路3.3 代码分析3.4 排序过程 4. …

十大经典排序算法----堆排序(超详细)

目录 1. 堆排序的基础知识 1.1 大顶堆&&小顶堆 1.2 向下调整算法 1.3 物理结构与逻辑结构的关系 2. 堆排序详解 2.1 堆排序整体思路 2.2 思路详解 2.2.1 建堆 2.2.2 大堆or小堆 2.2.3 输出数据 3. 时间复杂度分析 4. 完整代码 5. 彩蛋 1. 堆排序的基础知识…

【转载】堆排序算法(图解详细流程)

堆排序的时间复杂度O(N*logN),额外空间复杂度O(1)&#xff0c;是一个不稳定性的排序 目录 一 准备知识 1.1 大根堆和小根堆 二 堆排序基本步骤 2.1 构造堆 2.2 固定最大值再构造堆 三 总结 四 代码 一 准备知识 堆的结构可以分为大根堆和小根堆&#xff0c;是一个完全…

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

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 堆排序基本介绍大顶堆举例说明小顶堆举例说明堆排序的基本思想堆排序步骤图解说明堆排序的基本思路总结 堆排序基本介绍 堆排序是利用堆这种数据结构而设计的一种排…

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

什么是堆 堆是一种叫做完全二叉树的数据结构&#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系统本身就大…