一、综述
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
算法描述
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
平均算法复杂度是O(nlog2n),最好最坏都是这个。下面用Java实现一个归并排序,并用在使用辅助数组上做了小小的改进。
二、Java实现归并
public class AMergeSort {
/**
* 合并两个有序数组(从小到大)的方法
*
* @param a 传入的数组
* @param first 第一个有序序列开始的位置
* @param mid 中点位置
* @param last 第二个有序序列结束的位置
* @param tempArray 辅助数组
*/
public static void mergerArray(int[] a, int first, int mid, int last,
int[] tempArray) {
int newA = 0; // 指针,用指示新的,合并后的数组的元素
int i = first; // 第一个有序序列开始位置
int j = mid+1; // 第二个有序序列开始位置
while (i <=mid &j <= last) {// 两个序列都有元素
if (a[i] <= a[j]) { // 比较i,j位置的数,取小的进入新数组,被取的继续移动指针,另一个原地不动
tempArray[newA++] = a[i++];
} else {
tempArray[newA++] = a[j++];
}
}
// 可能只有一个数列有元素了,则直接把剩余的赋给新数组,下面两个while只有一个会执行
while (i <= mid) {
tempArray[newA++] = a[i++];
}
while (j <= last) {
tempArray[newA++] = a[j++];
}
//把辅助数组中的结果考回原数组(想想为什么不是<= ? 因为最后newA多加了1)
for(int n=0;n
=right) {// 中止条件
return;
}
int mid = (left + right) / 2;
// 递归调用,排序中间位置两边的数列
mergerSort(a, left, mid, tempArray); //使左边序列有序
mergerSort(a, mid + 1, right, tempArray); //使右边序列有序
// 两本数列有序后,将他们合并成一个一个有序数列
mergerArray(a, left, mid, right, tempArray);
}
}
三、结果检验
public class maintest {
public static void main(String[] args) {
int[] a = { 45, 6, 43, 78, 12, 90, 23, 21, 41, 64, 31, 91, 81, 6,45,89,43,12,13,33,99,456,789 };
int[] temp=new int[a.length];
AMergeSort.mergerSort(a, 0, a.length-1,temp);
for (int e : a) {
System.out.print(e + " ");
}
}
}
//运行结果为:6 6 12 12 13 21 23 31 33 41 43 43 45 45 64 78 81 89 90 91 99 456 789