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

作者:淡沫初夏Zz 时间:2023-10-20 02:00:11 

一、堆排序

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));
   }
}

运行截图:

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

二、时间复杂度分析

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+&hellip;+log(n-1)+log(n)&asymp;log(n!)。

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

3、总结

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

来源:https://blog.csdn.net/qq_55660421/article/details/122380669

标签:Java,堆排序,时间复杂度
0
投稿

猜你喜欢

  • Java毕业设计实战之仿小米电子产品售卖商城系统的实现

    2022-09-29 10:19:47
  • jvm细节探索之synchronized及实现问题分析

    2023-08-24 02:13:29
  • Android实现今日头条订阅频道效果

    2021-10-29 23:30:00
  • Java编程实现轨迹压缩算法开放窗口实例代码

    2021-12-03 09:54:07
  • 解决Tomcat启动报异常java.lang.ClassNotFoundException问题

    2023-07-27 03:33:01
  • Java线程安全解决方案(synchronized,ReentrantLock,Atomic)

    2022-06-13 12:51:09
  • C# 表达式目录树Expression的实现

    2023-04-03 22:57:32
  • RocketMQ消息过滤与查询的实现

    2023-06-26 10:04:25
  • Java超详细讲解设计模式之一的单例模式

    2023-03-09 10:59:09
  • Java C++题解leetcode 1684统计一致字符串的数目示例

    2023-04-23 09:06:31
  • Java @Deprecated注解的作用及传递性

    2023-08-11 12:55:05
  • Android ListView填充数据的方法

    2022-12-22 06:33:28
  • Java获取控制台输入的两种方法小结

    2023-11-29 12:40:44
  • Java客户端利用Jedis操作redis缓存示例代码

    2021-05-31 03:43:42
  • 深入讲解java线程与synchronized关键字

    2023-08-29 13:56:00
  • Java异常 Factory method'sqlSessionFactory'rew exception;ested exception is java.lang.NoSuchMethodError:

    2022-03-25 15:06:42
  • java实现用户自动登录

    2023-11-10 14:38:59
  • java判断回文数示例分享

    2023-03-20 03:18:22
  • 完美解决idea没有tomcat server选项的问题

    2022-02-12 04:20:54
  • Spring Security+JWT简述(附源码)

    2022-10-16 11:57:51
  • asp之家 软件编程 m.aspxhome.com