基础排序法之归并排序

归并排序

过程:一个数组,分成两个序列,通过递归(排序的方式)将左部分的值排好,再将右部分的值排好,左右两边排好后,再将两边的数据拿出来统一排好,即将两个有序数列合并为一个有序数列;

图画演示:

在这里插入图片描述
在这里插入图片描述
1、分散(从整到零)
将原始序列一刀切开,划分成两个序列。然后每个序列继续切开,又划分成两个更小的序列。

这样一层层地划分,可以得到一颗划分的树,树的叶子节点就是原始序列的每个元素了。

2、合并(从零到整)
从树的叶子节点开始沿着枝干往上合并,序列数越来越少,每个序列的长度越来越大,最终剩下一个序列,这个序列即为所求。

这时候注意,每次合并时,输入的是两个有序数列,输出的是一个合并之后的有序数列。

代码演示:

import java.util.Arrays;

public class 归并 {
	
	public static void mergeSort(int[] arr) {
		if(arr==null || arr.length<2) {
			return;
		}
		sortProcess(arr, 0, arr.length-1);;
	}
	
	public static void sortProcess(int[] arr, int L,int R) {
		if(L==R)
			return;
		int mid = L + ((R - L)>> 1); //L和R的中点
		sortProcess(arr,L,mid); 	  //arr的左部分(有序)
		sortProcess(arr, mid + 1, R); //arr的右部分(有序)
		merge(arr, L,  mid, R);		  //左右有序合并
	}
	
	public static void merge(int[]arr, int L, int mid, int R) {
		int[] help = new int[R-L+1];
		int i = 0;
		int p1 = L;
		int p2 = mid + 1;
		while(p1 <= mid && p2<= R) {
			help[i++] = arr[p1]<arr[p2] ? arr[p1++] : arr[p2++];
		}
		// 两个必有且只有一个越界
		while(p1 <= mid)
			help[i++] = arr[p1++];
		while(p2 <= R)
			help[i++] = arr[p2++];
		for(i = 0; i< help.length;i++)
			arr[L+i] = help[i];
	}
	public static void main(String[] args) {
		int[] arr = {1,9,8,7,5,25,45,6,2,3,0};
		mergeSort(arr);
		System.out.println(Arrays.toString(arr));
	}
}

3、复杂度
1)、时间复杂度
由“分散”和“合并”两部分组成。
“分散”:最后分成一个个的单一元素,因此复杂度为 O(n)。
“合并”:由于每次进行两两合并,因此合并的次数为 O(logn),而每次合并的复杂度为 O(n),因此整体合并的复杂度为 O(nlogn)。
因此,整个算法的时间复杂度为 O(nlogn)。
2)、空间复杂度
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为 O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值