算法排序(五)——归并排序法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/A1344714150/article/details/88699902

目的:使用归并排序法对随机数组进行排序

归并排序思路:假设数组有n个数,先将其分为两半,再对这两半继续对半分隔...重复操作直到分隔后的小部分只有一个数。接着对这两个数进行归并操作,归并后得到一个有序的两个数组成的小数组,再将其与另一个有序的两个数组成的小数组进行归并,重复操作,直到所有数组有序。

之所以要先不断分隔,是为了左右两侧内部要保证有序,才可以进行归并操作。

话不啰嗦,还是直接上代码吧:

	//归并排序法
	public static void mergeSort(int[] array){
		__mergeSort(array,0,array.length-1);
	}
	
	
	private static void __mergeSort(int[] array, int l, int r) {
		if(l>=r){
			return ;
		}
		
		int mid = (r-l)/2 + l;
		__mergeSort(array,l,mid);
		__mergeSort(array,mid+1,r);
		__merge(array,l,r,mid);
	}
	
	private static void __merge(int[] array,int l,int r,int mid){
		int[] temp = new int[r-l+1];
		for(int i=l;i<=r;i++){
			temp[i-l] = array[i]; 
		}
		
		int i = l;
		int j = mid+1;
		
		for(int k=l;k<=r;k++){
			if(i>mid){
				array[k] = temp[j-l];
				j++;
			}else if(j>r){
				array[k] = temp[i-l];
				i++;
			}else if(temp[i-l]<temp[j-l]){
				array[k] = temp[i-l];
				i++;
			}else{
				array[k] = temp[j-l];
				j++;
			}
		}
		
	}

排序结果:

基础版的归并排序法还可以接着优化。

优化一:如果现在两侧小数组组成的一部分已经完全有序了,可以直接跳过归并操作

private static void __mergeSort(int[] array, int l, int r) {
		if(l>=r){
			return ;
		}
		
		int mid = (r-l)/2 + l;
		__mergeSort(array,l,mid);
		__mergeSort(array,mid+1,r);
		if(array[mid]>array[mid])//如果左侧最大的数小于右侧最小的数,说明有序,不需要再归并了
		__merge(array,l,r,mid);
	}

优化二:当数组元素数量小的时候,可以进行优化版的插入排序法,提高在近乎有序的数组里的排序效率。

	private static void __mergeSort(int[] array, int l, int r) {
		if(r-l<=15){//如果个数小,其有序的可能性越大,尝试插入排序
			insertionSortBetter(array,l,r);
			return;
		}
		
		int mid = (r-l)/2 + l;
		__mergeSort(array,l,mid);
		__mergeSort(array,mid+1,r);
		if(array[mid]>array[mid])//如果左侧最大的数小于右侧最小的数,说明有序,不需要再归并了
		__merge(array,l,r,mid);
	}


    // 插入排序法优化
	public static void insertionSortBetter(int[] array,int l,int r) {
		for (int i = l+1; i <= r; i++) {
			int e = array[i];
			int j;
			for (j = i; j > l && e < array[j - 1]; j--) {
				array[j] = array[j - 1];
			}
			array[j] = e;
		}
 
	}

优化三:

将自顶向下的归并排序改为自底向上的归并排序,减少分隔的操作,不是经典的做法,这里就不列举了...

猜你喜欢

转载自blog.csdn.net/A1344714150/article/details/88699902