一 归并排序算法
- 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
- 首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。
二 代码实现
// 将有二个有序数列a[first...mid]和a[mid...last]合并
public static void mergearray(int[] src, int[] dest, int first, int mid, int last)
{
int i = first;
int j = mid + 1;
int k = 0;
while(i<=mid && j<=last)
{
if(src[i] > src[j])
{
dest[k++] = src[j++];
}else
{
dest[k++] = src[i++];
}
}
while(i<=mid)
dest[k++] = src[i++];
while(j<=last)
dest[k++] = src[j++];
for(i=0; i<k; i++)
{
src[first+i] = dest[i];
}
}
public static void mergesort(int[] src, int[] dest, int first, int last)
{
if(first < last)
{
int mid = (first+last)/2; // 二分分解
mergesort(src, dest, first, mid); //左边有序
mergesort(src, dest, mid+1, last); // 右边有序
mergearray(src, dest, first, mid, last); // 将有序序列合并
}
}
上面的代码可能不是很简洁,对其进行修改,得如下代码
public void sortIntegers2(int[] a) {
// Write your code here
mergeSort(a, new int[a.length], 0, a.length - 1);
}
public void mergeSort(int[] a, int[] temp, int left, int right){
if (left >= right) {
return;
}
int mid = (left + right) / 2;
mergeSort(a, temp, left, mid);
mergeSort(a, temp, mid + 1, right);
int p_final = left;
int p_left = left;
int p_right = mid + 1;
while (p_left <= mid || p_right <= right) {
if (p_left <= mid && (p_right > right || a[p_left] < a[p_right])) {
temp[p_final++] = a[p_left++];
} else {
temp[p_final++] = a[p_right++];
}
}
for (int i = left; i <= right; i++) {
a[i] = temp[i];
}
}
三 归并排序性质
- 归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。