归并排序

基本思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用 分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并


将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。

综上可知:

归并排序其实要做两件事:

(1)“分解”——将序列每次折半划分

(2)“合并”——将划分后的序列段两两合并后排序

归并排序算法复杂度O(n logn)。

public class MergeSort {
	/*
	 * 归并算法:先将数组分成两半,然后对着两半数组递归归并,递归条件是数组长度大于1;
	 * 最后得到的两个排好序的数组最后再进行归并,得到排序结果
	 */
	public static void mergeSort(int[] list){
		if(list.length > 1){
			int[] firstHalf = new int[list.length / 2];
			System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
			mergeSort(firstHalf);
			int secondHalfLength = list.length - list.length / 2;
			int[] secondHalf = new int[list.length - list.length / 2];
			System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength);
			mergeSort(secondHalf);
			
			int[] tmp = merge(firstHalf,secondHalf); 
			System.arraycopy(tmp, 0, list, 0, tmp.length);
		}
	}
	/*
	 * merge方法是将list1和list2两个有序数组进行归并;
	 * 方法是构造一个输出数组,长度为l1.length + l2.length
	 * 然后依次遍历l1、l2
	 * 将较小者赋给输出数组
	 */
	public static int[] merge(int[] list1,int[] list2){
		int[] tmp = new int[list1.length + list2.length];
		
		int current1 = 0; // for list1
		int current2 = 0; // for list2
		int current3 = 0; // for tmp
		
		while(current1 < list1.length && current2 < list2.length){
			if(list1[current1] < list2[current2]){
				tmp[current3 ++] = list1[current1 ++];
			}
			else
				tmp[current3 ++] = list2[current2 ++];
		}
		
		while(current1 < list1.length){
			tmp[current3 ++] = list1[current1 ++];
		}
		while(current2 < list2.length){
			tmp[current3 ++] = list2[current2 ++];
		}
		return tmp;
	}
	
	public static void main(String[] args){
		int[] list = {2,9,5,4,8,1,6,7};
		mergeSort(list);
		for(int element : list){
			System.out.println(element);
		}
	}
}


使用场景

归并排序多用于需要外部排序的场景,除此之外当内部排序需要保证稳定性时也采用归并排序(不要求稳定性的内部排序一般采用快排或者堆排序,前者在待排序序列基本有序时效率低,后者堆的维护是个问题)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值