二路归并排序的奥妙

   二路归并排序,顾名思义就是指将两个有序表组合成一个新的有序表。那么对于一个任意的待排序的数组,又该如何实现呢?
   让我们假设一个整形数组为{1,3,4,2,5},我们需要对它进行归并排序。按照我们刚才对二路归并的定义可知,我们得把这个数组一分为二,然后对左右两边的数组分别排序之后,再把两者归并到一起,就能将无序变为有序了。也许你会有疑问,我将原数组分成左右两个数组之后,又要用什么方法来给左右数组排序呢?不难想到,我们可以继续拆分数组,即将左边的数组看成待排序的数组,继续将其拆分成两个数组。同理,右边亦是如此。那么到什么时候拆分结束呢?很简单,当我们将数组拆分成仅有一个元素的数组时,拆分结束!因为继续拆分已经没意义了哦。
这样的话,你可能会问,拆分完成之后又该怎么归并呢?也许大家都会有或多或少的不习惯,因为我们是顺序将数组拆分,但需要逆序对数组归并。也就是说先归并元素个数为1的数组,再归并元素个数为2或更多的数组,直到最后只剩下两个数组,二者元素个数之和恰好为待排序数组元素之和。将二者归并之后,即得到顺序的数组。
   下面贴上我写的归并排序代码。
  
/**
 * 归并排序
 * 
 * @author Star
 * 
 */
public class MergeSortByStar {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int array[] = { 1, 3, 4, 2, 5, 57, 78, 23, 1 };
		mergeSort(array);
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}

	/**
	 * 
	 * @param array
	 *            待排序的数组
	 */
	public static void mergeSort(int array[]) {
		mSort(array, 0, array.length - 1);
	}

	/**
	 * 
	 * @param array
	 *            待排序数组
	 * @param start
	 *            排序的起点
	 * @param end
	 *            排序的终点
	 */
	private static void mSort(int array[], int start, int end) {
		if (start >= end)
			return;
		int center = (start + end) / 2;// 将数组拆分成两段
		//二路归并
		mSort(array, start, center);// 给左边的数组排序
		mSort(array, center + 1, end);// 给右边的数组排序
		merge(array, start, center, end);// 将左右两边的数组进行归并
	}

	/**
	 * 将左右两边的数组进行归并
	 * @param array
	 *            待排序数组
	 * @param start
	 *            排序起点
	 * @param center
	 *            排序中点
	 * @param end
	 *            排序终点
	 */
	private static void merge(int array[], int start, int center, int end) {
		int index = start;// 从第一个位置出发
		int i = start;
		int j = center + 1;
		int[] tmp = new int[end+1];//创建一个缓存数组
		//比较左右两边数组,并用缓存数组接收较小的数
		for (; i <= center && j <= end; index++) {
			if (array[i] < array[j])
				tmp[index] = array[i++];
			else
				tmp[index] = array[j++];
		}
		//缓存数组接受剩下的数据
		//如果左边还有的话,接受左边
		while (i <= center) {
			tmp[index++] = array[i++];
		}
		//如果右边还有的话,接受右边
		while (j <= end) {
			tmp[index++] = array[j++];
		}
		// 将临时数组复制给原数组
		while (start <= end) {
			array[start] = tmp[start];
			start++;
		}
	}
}

以上代码即是我之前分析的具体实现。如果大家对我有什么建议,欢迎指正,交流。
 

你可能感兴趣的:(java,排序)