理解合并排序,java中使用的标准排序方法

    所谓合并排序,就是将两个部分的数组合并在一起,但是有个前提就是两个数组本身就是已经排好序的。它包括两个问题,一个合并,一是排序。
    基本思想就是将一个数组从中间分为两个部分,先对左边排序,再对右边排序,最后将两边再合并出来即可了。采用递归手段,我们可以递归的对左边排序,对右边排序,最后合并。

    由于要将两个子数组合并为一个新的数组,因此需要一个额外的空间来存储这些数据信息。因此,我们需要建立一个与原数组大小相同的数组,用于合并过程。合并完了之后,再将额外空间中的数据copy回原来的空间,即完成整个排序工作。

    现在来看程序逻辑,程序逻辑已按照先分面两个部分,再分别递归排序,然后再合并的思路,具体代码如下:

	/** 归并排序,ints为要排序的数组 */
	public static void guibingSort(int[] ints) {
		int[] temp = new int[ints.length];
		guibingSort(ints, temp, 0, ints.length - 1);
	}

	/** 归并排序,ints为要进行排序的数组,temp为临时数组,start为排序起点,end为排序终点,排序范围为[start,end] */
	private static void guibingSort(int[] ints, int[] temp, int start, int end) {
		if(start >= end)
			return;
		int middle = (start + end) / 2;//中间点
		int left = start;//左边起点
		int right = middle + 1;//右边起点
		guibingSort(ints, temp, left, middle);//左边排序
		guibingSort(ints, temp, right, end);//右边排序
		//将两边的数组进行合并
		int i;
		for(i = start;  left <=  middle && right <= end;) {
			if(ints[left] > ints[right])
				temp[i++] = ints[right++];
			else
				temp[i++] = ints[left++];
		}
		//将左边没有合并完的添加到temp中
		while(left <= middle)
			temp[i++] = ints[left++];
		//将右边没有合并完的添加到temp中
		while(right <= end)
			temp[i++] = ints[right++];
		//最后将这些数字转回到ints
		System.arraycopy(temp, start, ints, start, end - start + 1);
	}

    代码的主要部分在于合并,合并的思路即对两个数组从开头分别比较,将比较小的那个加入到额外数组中去,这个过程一直持续到其中有一个数组完成,最后将剩下数组的剩余部分全部copy至额外数组即可(因为,两个数组是排好序的,在copy过程中可以保证排序的正确性)。

    合并排序与快速排序的最大一个区别在于,合并排序需要使用额外的空间,而且数据在排序过程中需要进行不断的进行数据之间的复制,并且用于比较的次数较小;而快速排序则需要对数据进行不断的移动,而不需要进行数据复制,却需要进行大量的比较操作。因为在java中,所有的数据都是按引用进行排序,数据移动和复制都是走引用,因此,花费较小,并且进行对象间的比较花费较大,因此在进行对象比较时,都是使用的合并排序算法。而其它语言,如c++,则是使用快速排序来进行排序,他们依赖的即是对象的大小比较。