归并排序是建立在归并操作上的一种有效的排序算法,该算法采用分治法的一个非常典型的应用。所谓归并排序是指将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(或有序表)。这样的排序方法经常用于多个有序的数据文件归并成一个有序的数据文件。时间复杂度为O(nlogn)。
归并排序的基本思想如下:
将长度为n的数组a[0,…..n-1]分为若干个子序列,每个子序列是有序的,再把有序的子序列合并为整体有序的序列。即递归地将数组前半部分a[0,…mid]和后半部分a[mid+1,…n-1]各自归并排序,得到排序后的两部分数据,再将这两部分合并在一起。
如下图所示(来自百度百科):
下面看一下合并过程:
public static void merge(int array[], int leftPos, int rightPos,
int rightEnd, int tempArray[]) {
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (array[leftPos] <= array[rightPos])
tempArray[tmpPos++] = array[leftPos++];
else
tempArray[tmpPos++] = array[rightPos++];
}
while (leftPos <= leftEnd)
tempArray[tmpPos++] = array[leftPos++];
while (rightPos <= rightEnd)
tempArray[tmpPos++] = array[rightPos++];
for (int i = 0; i < numElements; i++, rightEnd--)
array[rightEnd] = tempArray[rightEnd];
}
递归实现数组归并排序,递归的过程实际上就实现了数组的分解:
public static void mergesort(int array[], int left, int right, int tempArray[]) {
if (left < right) {
int mid = (left + right) / 2;
mergesort(array, left, mid, tempArray);
mergesort(array, mid + 1, right, tempArray);
merge(array, left, mid + 1, right, tempArray);
}
}
最终代码如下:
public class mergeSort {
public static void merge(int array[], int leftPos, int rightPos,
int rightEnd, int tempArray[]) {
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (array[leftPos] <= array[rightPos])
tempArray[tmpPos++] = array[leftPos++];
else
tempArray[tmpPos++] = array[rightPos++];
}
while (leftPos <= leftEnd)
tempArray[tmpPos++] = array[leftPos++];
while (rightPos <= rightEnd)
tempArray[tmpPos++] = array[rightPos++];
for (int i = 0; i < numElements; i++, rightEnd--)
array[rightEnd] = tempArray[rightEnd];
}
public static void mergesort(int array[], int left, int right, int tempArray[]) {
if (left < right) {
int mid = (left + right) / 2;
mergesort(array, left, mid, tempArray); // 递归的使左边有序
mergesort(array, mid + 1, right, tempArray); // 递归的使右边有序
merge(array, left, mid + 1, right, tempArray); // 将二个有序数列合并
}
}
public static void MergeSort(int array[]) {
int[] temp = new int[array.length];
mergesort(array, 0, array.length - 1, temp);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = { 5, 3, 19, 10, 8, 2, 11, 7 };
MergeSort(a);
for (int x = 0; x < a.length; x++) {
System.out.println(a[x]);
}
}
}
本文主要参考《数据结构与算法分析 Java语言描述》