Java详细讲解堆排序与时间复杂度的概念

 更新时间:2022年04月26日 11:20:53   作者:淡沫初夏Zz  
本文主要介绍了java实现堆排序以及时间复杂度,堆排序这种排序算法是我们经常用到的,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、堆排序

1、什么是堆排序

(1)堆排序:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

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

2、堆排序思想

(1)将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆

(2)将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端

(3)重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序

3、代码实现

import java.util.Arrays;
public class Sort {
     //将任意数组进行原地堆排序
    public static void heapSort(int[] arr) {
        //把数组调整为最大堆,从最后一个非叶子节点开始下沉
        for (int i = (arr.length-1-1)/2; i >= 0; i--) {
            siftDown(arr,i,arr.length);
        }
        //将堆顶元素和最后一个元素交换
        for (int i = arr.length-1; i > 0 ; i--) {
            swap(arr,0,i);
            siftDown(arr,0,i);
        }
    }
   //下沉操作
    private static void siftDown(int[] arr, int i, int n) {
        while ((2 * i)+1 < n){
            int j = (2 * i) + 1;
            if(j+1<n && arr[j+1]>arr[j]){
               j = j+1;
            }
            if(arr[i] >= arr[j]){
                break;
            }else{
                swap(arr,i,j);
                i = j;
            }
        }
    }
     public static void main(String []args){
        int []arr = {7,6,7,11,5,12,3,0,1};
        System.out.println("排序前:"+ Arrays.toString(arr));
        heapSort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
    }
}

运行截图:

二、时间复杂度分析

1、初始化建堆

初始化建堆只需要对二叉树的非叶子节点由下至上,由右至左选取非叶子节点来调用adjusthead()函数。那么倒数第二层的最右边的非叶子节点就是最后一个非叶子结点。

 假设高度为k,则从倒数第二层右边的节点开始,这一层的节点都要执行子节点比较然后交换;倒数第三层呢,则会选择其子节点进行比较和交换,如果没交换就可以不用再执行下去了。高层也是这样逐渐递归。

 那么总的时间计算为:s = 2^( i - 1 ) * ( k - i );其中 i 表示第几层,2^( i - 1) 表示该层上有多少个元素,( k - i) 表示子树上要下调比较的次数。

S = n - log(n) -1,所以时间复杂度为:O(n)

2、排序重建堆

每次重建意味着有一个节点出堆,所以需要将堆的容量减一。adjustheap()函数的时间复杂度k=log(n),k为堆的层数。所以在每次重建时,随着堆的容量的减小,层数会下降,函数时间复杂度会变化。重建堆一共需要n-1次循环,每次循环的比较次数为log(i),则相加为:log2+log3+…+log(n-1)+log(n)≈log(n!)。

所以时间复杂度为O(nlogn)

3、总结

初始化建堆的时间复杂度为O(n),排序重建堆的时间复杂度为nlog(n),所以总的时间复杂度为O(nlogn),空间复杂度为O(1)。

到此这篇关于Java详细讲解堆排序与时间复杂度的概念的文章就介绍到这了,更多相关Java堆排序与时间复杂度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Stream实现多字段分组groupingBy操作详解

    Java Stream实现多字段分组groupingBy操作详解

    Stream是Java8的一个新特性,主要用户集合数据的处理,如排序、过滤、去重等等功能,本文就来讲讲如何利用Stream实现比较优雅的按多字段进行分组groupingBy吧
    2023-06-06
  • SpringBoot2开发从0开始Spring Initailizr初始化

    SpringBoot2开发从0开始Spring Initailizr初始化

    这篇文章主要为大家介绍了SpringBoot2从0开始lombok、devtools、Spring Initailizr的开发技巧,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 详解JavaFX桌面应用开发-Group(容器组)

    详解JavaFX桌面应用开发-Group(容器组)

    这篇文章主要介绍了JavaFX桌面应用开发-Group(容器组),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Maven分模块开发执行指令失败的问题

    Maven分模块开发执行指令失败的问题

    Maven分模块开发,行指令失败,modules.module[3]‘ specifies duplicate child module maven_dao @ line 29, column 1的问题,本文给大家分享解决方法,感兴趣的朋友跟随小编一起看看吧
    2020-09-09
  • SpringBoot集成消息队列的项目实践

    SpringBoot集成消息队列的项目实践

    本文主要介绍了SpringBoot集成消息队列的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • Java文本文件操作方法实例详解

    Java文本文件操作方法实例详解

    这篇文章主要介绍了Java文本文件操作方法,以实例形式较为详细的分析了java操作文本文件的相关技巧,需要的朋友可以参考下
    2015-06-06
  • Springboot 使用内置tomcat禁止不安全HTTP的方法

    Springboot 使用内置tomcat禁止不安全HTTP的方法

    这篇文章主要介绍了Springboot 使用内置tomcat禁止不安全HTTP的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java锁之自旋锁详解

    Java锁之自旋锁详解

    这篇文章主要介绍了Java锁之自旋锁详解,本文是系列文章的第一篇,请持续关注脚本之家java栏目,需要的朋友可以参考下
    2014-09-09
  • Java中的四种单例模式浅析

    Java中的四种单例模式浅析

    这篇文章主要给大家介绍了关于Java中四种单例模式的相关资料,其中包括饿汉式、懒汉式、懒汉式(双重锁)及内部类等四种,分别给出了详细的示例代码和介绍,需要的朋友们下面来一起看看吧。
    2017-05-05
  • 面试题:Java 实现查找旋转数组的最小数字

    面试题:Java 实现查找旋转数组的最小数字

    这篇文章主要介绍了Java 实现查找旋转数组的最小数字,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07

最新评论