归并排序(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]