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到底是值传递还是引用传递呢

    浅谈Java到底是值传递还是引用传递呢

    今天带大家学习Java的相关知识,文章围绕着Java到底是值传递还是引用传递展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Java字符串格式化功能 String.format用法详解

    Java字符串格式化功能 String.format用法详解

    String类的format()方法用于创建格式化的字符串以及连接多个字符串对象,熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处,format()方法有两种重载形式
    2024-09-09
  • Java 8 新特性终极版指南详解

    Java 8 新特性终极版指南详解

    Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。本文给大家介绍Java 8 新特性终极版指南详解,需要的朋友参考下
    2016-03-03
  • 学习Java之异常到底该如何捕获和处理

    学习Java之异常到底该如何捕获和处理

    我们知道,Java的异常处理是通过5个关键字来实现的,即try、catch、throw、throws和finally,try catch语句用于捕获并处理异常,但具体该怎么捕获异常,怎么抛出异常,什么时候抛,什么时候捕,感兴趣的小伙伴跟着小编一起来看看吧
    2023-08-08
  • SpringBoot 动态配置邮箱发件人过程解析

    SpringBoot 动态配置邮箱发件人过程解析

    这篇文章主要介绍了SpringBoot 动态配置邮箱发件人过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Spring中@Autowired注解作用在方法上和属性上说明

    Spring中@Autowired注解作用在方法上和属性上说明

    这篇文章主要介绍了Spring中@Autowired注解作用在方法上和属性上说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 解决SpringMVC拦截器path路径的坑

    解决SpringMVC拦截器path路径的坑

    这篇文章主要介绍了解决SpringMVC拦截器path路径的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 在Java中使用MongoDB的方法详解

    在Java中使用MongoDB的方法详解

    这篇文章主要给大家介绍了关于在Java中使用MongoDB的相关资料,要操作MongoDB数据库你需要使用MongoDB的Java驱动程序,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • java求整数的位数方式

    java求整数的位数方式

    这篇文章主要介绍了java求整数的位数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Spring Boot整合RabbitMQ开发实战详解

    Spring Boot整合RabbitMQ开发实战详解

    这篇文章主要介绍了Spring Boot整合RabbitMQ开发实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02

最新评论