归并排序---java版

归并排序

归并排序采用分治法,需要辅助空间来存放需要 排序的小数组排序好的数组再整合的数组,因为使用了分路递归,所以时间复杂度都是O(nlogn),核心想法就是,假设有数组长度为10,一直对半拆分,最后剩2个数字排序,递归整合后再整合

下面代码将分为10小点讲解思想,对应的点在代码后的注释

其代码如下

static int[] mergeSort(int...arr) {
		if(arr.length<2) return arr;                              //-----------000------------
		int mid = arr.length/2;                                   //-----------111------------
		int[] left = Arrays.copyOfRange(arr, 0, mid);             //-----------222------------
		int[] right = Arrays.copyOfRange(arr,mid, arr.length);    //-----------333------------
		return merge(mergeSort(left),mergeSort(right));           //-----------444------------
	}

	static int[] merge(int[] left, int[] right) {
		int[] result = new int[left.length+right.length];          //-----------555------------
		for(int l=0,r=0,index=0;index<result.length;++index) {
			if(l<left.length && r<right.length) {                  //-----------666------------  
				if(left[l]<right[r]) {                             //-----------777------------
					result[index] = left[l++];
				}else {
					result[index] = right[r++];
				}
			}else if(l<left.length) {               //-----------888------------
				result[index] = left[l++];
			}else if(r<right.length) {             //-----------999------------
				result[index] = right[r++];
			}
		}
		return result;
	}

讲解:

代码000:

对半拆分到不可再分后直接返回结果,否则继续拆分

代码111:

拆分点计算

代码222&代码333:

根据拆分点,拆分成左右2个数组

代码444:

递归拆分直到拆分成一个数字,最后调用合并函数 merge(int[] left,int[] right)

代码555:

归并方法,排序好的数组再整合的数组,再解释: 数组sum = 左数组 +右数组

代码666:

数组sum 依次插入数据

代码777:

如果左数组的当前下标数对应值小于 右数组的当前下标数对应的值,数组sum 当前下位置的值等于左数组当前下标数对应的值,并且左数组的索引指标+1 ,反之亦如

代码888:

当右数组放完,直接放左数组的值过去,无需再比较

代码999:

当左数组放完,直接放右数组的值过去,无需再比较


其时间比较花费分析:

与java内部排序算法相比较:

数组长度为1000时:

手写归并排序--运行花费时间: 0ms
java内部排序工具--运行花费时间: 1ms

数组长度为10000时:

手写归并排序--运行花费时间: 4ms
java内部排序工具--运行花费时间: 2ms

数组长度为100000时:

手写归并排序--运行花费时间: 27ms   //个人测试最大时间未59MS  --  最小20
java内部排序工具--运行花费时间: 10ms

数组长度为1000000时(3组数据):

手写归并排序--运行花费时间: 174ms
java内部排序工具--运行花费时间: 125ms
手写归并排序--运行花费时间: 154ms
java内部排序工具--运行花费时间: 48ms
手写归并排序--运行花费时间: 156ms
java内部排序工具--运行花费时间: 108ms

数组长度为10000000时(3组数据):

手写归并排序--运行花费时间: 1590ms
java内部排序工具--运行花费时间: 406ms
手写归并排序--运行花费时间: 1545ms
java内部排序工具--运行花费时间: 442ms
手写归并排序--运行花费时间: 1504ms
java内部排序工具--运行花费时间: 385ms

总结:数据越大排序时间约稳定,但速度还是比不过java的排序工具,自己总结的算法性能也不够以后会改进,也会找时间对java本身的排序工具写个文章


测试代码

public static void main(String[] args) {
		int[] arr = new int[10000000];
		Random r = new Random();
		for(int i=0;i<arr.length;i++)
			arr[i]=r.nextInt(100);
		int[] arr1 =arr;
		long currentTimeMillis1 = System.currentTimeMillis();
		mergeSort(arr);
		long currentTimeMillis2 = System.currentTimeMillis();
		long currentTimeMillis3 = System.currentTimeMillis();
		Arrays.sort(arr1);
		long currentTimeMillis4 = System.currentTimeMillis();
		System.out.println("手写归并排序--运行花费时间: "+(currentTimeMillis2-currentTimeMillis1)+"ms");
		System.out.println("java内部排序工具--运行花费时间: "+(currentTimeMillis4-currentTimeMillis3)+"ms");
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值