数据结构的堆排序_数据结构冒泡排序算法

数据结构的堆排序_数据结构冒泡排序算法一、什么是堆排序1.堆,堆排序对于“堆”我们可以理解为具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆堆

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、什么是堆排序

1.堆,堆排序

对于“”我们可以理解为具有以下性质的完全二叉树

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

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

在排序时,一般升序采用大顶堆,降序采用小顶堆。

2.大顶堆

数据结构的堆排序_数据结构冒泡排序算法

我们可以看到,层数从小到大,节点的数字是越来越小的,映射到数组有:{50,45,40,20,25,35,30,10,15}

特点是arr[i] >= arr[2*i+1] && arr[i] >= arr[2*i+2]

3.小顶堆

image-20200714202759899

跟大顶堆相反,层数从小到大,节点的数字是越来越大,映射到数组:{10,20,15,25,50,30,40,35,45}

特点是:arr[i] <= arr[2*i+1] && arr[i] <= arr[2*i+2]

二、堆排序的思路分析

1.概述

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

2.举个例子

对数组{4,6,8,5,9}进行排序。

第一遍排序

  1. 我们从最后一个非叶子结点开始排序。第一个非叶子结点为arr.length/2-1=5/2-1=1,也就是元素6.,我们对他进行对比并调整位置;

    数据结构的堆排序_数据结构冒泡排序算法

  2. 在{6,5,4}中,5比6小,而9比6大,所以9和6交换位置;

    image-20200716171927431

  3. 接着找到第二个非叶子节点4,由于9是{9,4,8}这个树中最大的,故9与4交换位置

    image-20200716172640232

  4. 由于9与4交换位置打乱了原先{9,5,6}这棵树顺序,所以继续对新树{4,5,6}进行排序

    image-20200716172926921

  5. 由此得到了一个大顶堆,然后将堆顶元素9与末尾元素4进行交换,得到数组{4,6,8,5,9}

    image-20200716173427122

至此,第一遍排序已经完成,我们确定了最大元素9的位置

第二遍排序

第二遍排序开始时,最大元素9的位置已经确定,实际上要排序的数组变成了{4,6,8,5}

  1. 继续从6开始比较,{6,5}排序正常,所以接着比较{4,6,8},8是最大的,所以与4交换位置

    image-20200716184743652

  2. 由此得到了一个大顶堆,然后将堆顶元素8与末尾元素5进行交换,得到数组{8,6,4}

    image-20200716184933083

至此,第一遍排序已经完成,我们确定了最第二大元素8的位置

第三遍~第n遍排序

第二遍排序开始时,最大元素9和第二大元素8的位置已经确定,实际上要排序的数组变成了{5,6,4}

重复比较-排序-交换堆顶和队尾元素位置这一过程,直到最终获得有序数列

image-20200716185250532

三、代码实现

/**
 * @Author:CreateSequence
 * @Date:2020-07-16 16:53
 * @Description:堆排序
 */
public class HeapSort {

    /**
     * 对数组进行堆排序
     * @param arr
     * @return
     */
    public static int[] sort(int[] arr) {
        //将无序数组构建成一个大/小顶堆
        //有几个非叶子节点就排序几次
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            sortHeap(arr,i,arr.length);
        }

        int temp = 0;
        //交换数组头尾元素,将最大的元素排沉到队尾
        for (int i = arr.length - 1; i > 0; i--) {
            //交换头尾元素
            temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            //1.交换完后,此时最大的元素在arr[0],最小的元素在arr[i],即确定了本次排序范围最大的数
            //2.然后对0~i-1的范围进行排序,重新获得的数组最小的元素在arr[0],最大的元素在arr[i-1]
            sortHeap(arr, 0, i);
            
            //3.接着进入下一次循环,重复步骤1,2,每次循环排序范围都缩小一位
        }

        return arr;
    }

    /**
     * 将以非叶子节点i为根节点的树调整为一个大顶堆
     * @param arr 要调整的数组
     * @param i 非叶子结点在数组中的下标
     * @param length 要调整的数组长度
     */
    public static int[] sortHeap(int[] arr, int i, int length) {
        if (arr == null || arr.length == 0) {
            throw new RuntimeException("数列必须至少有一个元素!");
        }

        //获取根节点值
        int temp = arr[i];

        //从左节点开始遍历
        for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
            //比较左右节点大小,将j指向值大的节点
            if (j + 1 < length && arr[j + 1] > arr[j]) {
                j = j + 1;
            }
            //比较将左右节点与父节点大小
            if (arr[j] > temp) {
                //如果子节点大于父节点,交换两节点位置
                arr[i] = arr[j];
                //然后继续从该子节点向下遍历
                i = j;
            }else {
                break;
            }
        }

        //结束循环时,arr[i]已经存放了以原arr[i]为根节点的树的最大值
        arr[i] = temp;

        return arr;
    }

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170805.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python实现向量自回归(VAR)模型——完整步骤「建议收藏」

    废话不多说,先开始分享:1.首先啥是VAR模型,我这里简略通俗的说一下,想看代码的童鞋直接跳到第3部分就好了:以金融价格为例,传统的时间序列模型比如ARIMA,ARIMA-GARCH等,只分析价格自身的变化,模型的形式为:其中称为自身的滞后项。但是VAR模型除了分析自身滞后项的影响外,还分析其他相关因素的滞后项对未来值产生的影响,模型的形式为:其中就是其他因子的滞后项…

    2022年4月15日
    1.2K
  • 苹果套路直播计算机隐藏版,套路计算器app,套路计算器隐藏官网版app预约 v1.0 – 浏览器家园…

    苹果套路直播计算机隐藏版,套路计算器app,套路计算器隐藏官网版app预约 v1.0 – 浏览器家园…套路计算器隐藏官网版app软件是一款最新人气计算器玩法,大家可以在这里发现非常多有趣的玩法,超级适合大家进行整蛊以及活跃气氛适应的,计算器里面会有各种好玩有趣的公式,帮你计算出各种想要的问题回答,非常类似于星座方面的玩法,说不定可以帮你解决你心中的各种问题疑问,如果你想尝试的话,就赶紧下载体验吧。套路计算器隐藏官网版app软件特色:1、玩法非常简单,输入自己的想要提的问题,就可以自动算出结果!2、…

    2022年4月30日
    549
  • 腾讯课堂下载回放视频课程记录_腾讯课堂回放下载

    腾讯课堂下载回放视频课程记录_腾讯课堂回放下载腾讯课堂下载回放视频对于爱学习的童鞋来说,能把腾讯课堂上的视频下载下来,随时随地听课,那该有多好啊!但是,腾讯课堂采取了多种加密措施,导致下载视频难上加难……要想下载视频,必须分为两部分进行,先获取视频的m3u8地址,然后用m3u8地址下载视频。第一步,获取视频m3u8地址:下面用两款热门浏览器:360安全浏览器和谷歌浏览器进行演示。①360浏览器:…

    2025年7月24日
    4
  • 有序的四字成语_LinkedHashMap

    有序的四字成语_LinkedHashMapHashMap是无序的,HashMap在put的时候是根据key的hashcode进行hash然后放入对应的地方。所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟put的顺序不同(除非在put的时候key已经按照hashcode排序号了,这种几率非常小)单纯的HashMap是无法实现排序的,这的排序是指,我们将键值对按照一定的顺序put进HashMap里,然后在进行

    2022年9月23日
    6
  • OpenGrok简单使用说明「建议收藏」

    OpenGrok简单使用说明「建议收藏」opengrok查看android源码简单的使用说明,快速搜索定位代码位置。。

    2022年5月6日
    55
  • pycharm run/debug configurations配置_linux中run文件怎么安装

    pycharm run/debug configurations配置_linux中run文件怎么安装0、Run/DebugConfigurations的坑在安装完PyCharm后,配置好Settings里的ProjectInterpreter,这里就是配置pythoy的解释器。之后运行的时候按Ctrl+Shift+F10运行编辑器的配置,帮你自动配置好Run/DebugConfigurations并运行,而运行另一个文件或新文件时再按Ctrl+Shift+…

    2022年8月28日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号