归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
归并操作的过程如下:
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针达到序列尾
5. 将另一序列剩下的所有元素直接复制到合并序列尾
如图:
归并排序中中两件事情要做:
第一:“分”, 就是将数组尽可能的分,一直分到原子级别。
第二:“并”,将原子级别的数两两合并排序,最后产生结果。
代码实现:
public class MergeSort {
/***
* 数组的划分
*
* @param array 待排序数组
* @param temparray 临时存放数组
* @param left 序列段的开始位置
* @param right 序列段的开始位置
*/
public static void mergeSort(int[] array, int[] temparray, int left,
int right) {
if (left < right) {
// 取分割位置
int middle = (left + right) / 2;
// 递归划分数组左序列
mergeSort(array, temparray, left, middle);
// 递归划分数组右序列
mergeSort(array, temparray, middle + 1, right);
// 数组合并操作
merge(array, temparray, left, middle + 1, right);
}
}
/***
* 数组的两两合并操作
*
* @param array 待排序数组
* @param temparray 临时数组
* @param left 第一个区间段开始位置
* @param middle 第二个区间的开始位置
* @param right 第二个区间段结束位置
*/
public static void merge(int[] array, int[] temparray, int left,int middle, int right) {
// 左指针尾
int leftEnd = middle - 1;
// 右指针头
int rightStart = middle;
// 临时数组的下标
int tempIndex = left;
// 数组合并后的length长度
int tempLength = right - left + 1;
// 先循环两个区间段都没有结束的情况
while ((left <= leftEnd) && (rightStart <= right)) {
// 如果发现有序列大,则将此数放入临时数组
if (array[left] < array[rightStart])
temparray[tempIndex++] = array[left++];
else
temparray[tempIndex++] = array[rightStart++];
}
// 判断左序列是否结束
while (left <= leftEnd)
temparray[tempIndex++] = array[left++];
// 判断右序列是否结束
while (rightStart <= right)
temparray[tempIndex++] = array[rightStart++];
// 交换数据
for (int i = 0; i < tempLength; i++) {
array[right] = temparray[right];
right--;
}
}
/**
* @param args
*/
public static void main(String[] args) {
int[] array = {2,5,1,8,9,3};
System.out.println("排序前:"+Arrays.toString(array));
mergeSort(array, new int[array.length], 0, array.length - 1);
System.out.println("排序后:"+Arrays.toString(array));
}
}
输出结果:
排序前:[2, 5, 1, 8, 9, 3]
排序后:[1, 2, 3, 5, 8, 9]