归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾。
具体工作原理如下(假设序列共有n个元素):
1.将序列每相邻两个数字进行归并操作(merge),形成floor(n/2+n%2)个序列,排序后每个序列包含两个元素
2.将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
重复步骤2,直到所有元素排序完毕。
package com.test; public class MergeSort { /** * @param source 源数组 * @param temp 临时数据 * @param start 起始索引 * @param middle 索引的中间值 * @param end 结束索引 */ public static void merge(int[] source,int[] temp,int start,int middle,int end){ int i = start; int k = start; int j = middle+1; while(i!= middle+1 && j !=end+1){ if(source[i] > source[j]){ temp[k++] =source[j++]; }else{ temp[k++] = source[i++]; } } //其中一半的数据已全部放入临时数组中,就将余下的数据,放到临时数组中,使用两组判断,每次调用只执行一个。 while(i != middle+1){ temp[k++] = source[i++]; } while(j != end+1){ temp[k++] = source[j++]; } //将临时数组的数据赋值到原始数组。 for ( i = start; i <= end ; i++) { source[i] = temp[i]; } } /** * 递归实现归并 * @param source 源数组 * @param temp 临时数组 * @param start 起始索引 * @param end 结束索引 */ public static void mergeSort(int[] source,int[] temp,int start,int end){ int middle; if (start < end){ middle = start + (end-start)/2; mergeSort(source,temp,start,middle); mergeSort(source,temp,middle+1,end); merge(source,temp,start,middle,end); } } public static void main(String[] args) { int[] a = {1,23,21,32,12,3,2,4,12,21}; int[] temp = new int[a.length]; mergeSort(a,temp,0,a.length-1); for (int i:a) { System.out.print(i+"\t"); } } }