java实现堆排序以及时间复杂度的分析

 更新时间:2021年12月10日 09:41:59   作者:朱季谦  
本文主要介绍了java实现堆排序以及时间复杂度,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

完全二叉树:从上到下,从左到右,每层的节点都是满的,最下边一层所有的节点都是连续集中在最左边。

二叉树的特点就是左子节点是父节点索引值的2倍加一,右子节点是父节点索引值的2倍加二

堆分为两种:大顶堆和小顶堆

        大顶堆:在完全二叉树基础上,每个节点的值都大于或等于其左右子节点的值

        小顶堆:在完全二叉树基础上,每个节点的值都大于或等于其左右子节点的值

堆排序就是根据先构建好的大顶堆或小顶堆进行排序的。

怎么构建大顶堆:

        假如一个数组是:int[] arr= {3,5,7,9,1,2,4,6,8,11,10};它的完全二叉树形状如下图所示:

红色数字的是节点在数组中的索引值,它们之间的关系就是左子节点是父节点索引值的2倍加一,右子节点是父节点索引值的2倍加二

 我们想把它构建成大顶堆就从二叉树最下面一层开始也就是从最后一个数组开始,先比较左右子树,找到最大的一个,用最大的和父节点进行比较如果子节点大就进行交换,交换结束后再比较此层左边的左右和父子节点进行交换。也就是从最下一层开始,从右到左开始比较,此层比较完进入上一层再从右到左开始比较以此循环。当到达上一层时会有一个问题就是如果换下来的父节点比子节点小我们还需要往下进行交换,我们就需要对它进行维护。

上面数组的例子按顺序构建的大顶堆如下图所示:

 

 

 

 

 构建好的大顶堆的根节点总是最大的,我们根据这个特点进行排序。

我们把根节点和树的最后一个叶子节点进行交换即让数组的第一个数和最后一个数交换,交换后让最后一个数保持位置不再变化,我们再让其他节点再进行维护大顶堆,因为此时根节点是比子节点小的,重复以上操作直到需要根节点和他本身进行交换时排序完成

排序流程图如下:

 

 

 

 

 

 

 

 

 

代码如下:

public class heapsort {
	public static void main(String[] args) {
		int[] arr= {3,5,7,9,1,2,4,6,8,11,10};
		for(int p=arr.length-1;p>=0;p--) {
			adjustheap(arr,p,arr.length);
		}
		heapsort(arr);
		System.out.println(Arrays.toString(arr));
	}
 
	public static void heapsort(int[] arr) {
		for(int i=arr.length-1;i>=0;i--) {
			int temp=arr[i];
			arr[i]=arr[0];
			arr[0]=temp;
			adjustheap(arr, 0, i);
		}
		
	}
 
	public static void adjustheap(int[] arr, int p, int length) {
		int temp=arr[p];
		int left=p*2+1;
		while(left<length) {
			if(left+1<length&&arr[left]<arr[left+1]) {
				left++;
			}
			if(temp>arr[left]) {
				break;
			}
			arr[p]=arr[left];
			p=left;
			left=left*2+1;
			
		}
		arr[p]=temp;
	}

 输出结果如下:

 时间复杂度:构建大顶堆的时间复杂度是O(nlogn),n是main方法里的for循环,logn是构建大顶堆的方法的时间复杂度,排序的时间复杂度也是O(nlogn),所以堆排序的时间复杂度是O(nlogn)+O(nlogn),也就是O(logn)

到此这篇关于java实现堆排序以及时间复杂度的分析的文章就介绍到这了,更多相关java 堆排序及时间复杂度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详细讲解Java中==与equals的区别对比

    详细讲解Java中==与equals的区别对比

    这篇文章主要为大家详细介绍了Java中==与equals的区别对比,文中有详细的代码示例供大家参考,具有一定的参考价值,感兴趣的同学可以参考阅读下
    2023-09-09
  • java格式化时间示例

    java格式化时间示例

    这篇文章主要介绍了java格式化时间示例,需要的朋友可以参考下
    2014-04-04
  • MyBatis动态创建表的实例代码

    MyBatis动态创建表的实例代码

    在项目需求中,我们经常会遇到动态操作数据表的需求,常见的我们会把日志、设备实时位置信息等存入数据表,并且以一定时间段生成一个表来存储。接下来通过本文给大家介绍MyBatis动态创建表的方法,感兴趣的朋友一起看看吧
    2018-07-07
  • java Signleton模式详解及示例代码

    java Signleton模式详解及示例代码

    Singleton模式是创建模式。这种模式只涉及一个类是负责创建自己的对象。该类确保只有一个对象获得创建。这个类提供了一种方法来访问它的唯一对象
    2016-10-10
  • Spring/Spring Boot 中优雅地做参数校验拒绝 if/else 参数校验

    Spring/Spring Boot 中优雅地做参数校验拒绝 if/else 参数校验

    这篇文章主要介绍了Spring/Spring Boot 中优雅地做参数校验拒绝 if/else 参数校验,本文使用最新的 Spring Boot 版本 2.4.5,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-04-04
  • 使用mybatisPlus的queryWrapper做左联接,内联接方式

    使用mybatisPlus的queryWrapper做左联接,内联接方式

    本文介绍了如何使用Mybatis-Plus的QueryWrapper进行SQL查询,包括左连接、内连接等操作,通过示例代码展示了如何构建复杂的SQL查询,并将结果存储在List对象中返回,希望给读者提供参考
    2025-03-03
  • Spring Boot中整合Spring Security并自定义验证代码实例

    Spring Boot中整合Spring Security并自定义验证代码实例

    本篇文章主要介绍了Spring Boot中整合Spring Security并自定义验证代码实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 如何用java编写微信小程序消息提醒推送

    如何用java编写微信小程序消息提醒推送

    最近参与开发的项目有用到微信模板消息推送,在这离记录一下,下面这篇文章主要给大家介绍了关于如何用java编写微信小程序消息提醒推送的相关资料,需要的朋友可以参考下
    2023-11-11
  • java使用链表实现约瑟夫环

    java使用链表实现约瑟夫环

    这篇文章主要为大家详细介绍了java使用链表实现约瑟夫环,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • Java时间复杂度、空间复杂度的深入详解

    Java时间复杂度、空间复杂度的深入详解

    对于一个算法,其时间复杂度和空间复杂度往往是相互影响的,当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间,这篇文章主要给大家介绍了关于Java时间复杂度、空间复杂度的相关资料,需要的朋友可以参考下
    2021-11-11

最新评论