归并排序使用了分治思想,操作模式如下:
1 分解 分解待排序的n的元素成各具n/2个元素的两个数组
2 解决 使用归并排序递归地排序两个数组
3 合并 合并两个已排序的数组
//上面的三个步骤会被递归调用
下面我们来看看合并步骤的伪代码
MERGE(A,p,q,r) // p<=q<r
1 n1=q-p+1
2 n2=r-p
3 let L[1..n1+1] and R[1..n2+1] be new arrarys
4 for i=0 to n1
5 L[I]=A[p+i-1]
6 for j=0 to n2
7 L[j]=A[q+j]
8 L[n1+1]=∞
9 L[n2+1]=∞
10 i=1
11 j=1
12 for k=p to r
14 if L[i]<=R[j]
15 A[k]=L[i]
16 i++
17 else A[k]=R[j]
j++
下面我们来看看排序的伪代码
MERGE-SORT(A,p,r)
1 if p<r
2 q(p+r)/2
3 MERGE-SORT(A,p,q)
4 MERGE-SORT(A,q+1,r)
5 MERGE(A,p,q,r)
Java 实现归并排序算法代码
import org.junit.Test;
/**
* Created by WuNanliang on 2017/5/6.
*/
public class MergeSort {
@Test
public void test() {
int[] arr = {1, 2, 3, 2, 1, 3, 45, 44, 55, 33, 54, 213, 6, 10};
mergeSort(arr, 0, arr.length - 1);
for (int i : arr)
System.out.print(" " + i);
}
/**
* 归并排序
*
* @param arr 待排序数组
* @param leftPos
* @param rightPos
*/
private void mergeSort(int[] arr, int leftPos, int rightPos) {
if (leftPos >= rightPos)
return;
int middlePos = (leftPos + rightPos) / 2;
mergeSort(arr, leftPos, middlePos);
mergeSort(arr, middlePos + 1, rightPos);
merge(arr, leftPos, middlePos, rightPos);
}
/**
* @param arr 数组
* @param left 左边界
* @param middle 待合并两个数组的分界
* @param right 右边界
*/
private void merge(int[] arr, int left, int middle, int right) {
int leftLen = middle - left + 1;
int rightLen = right - middle;
int[] leftArr = new int[leftLen];
int[] rightArr = new int[rightLen];
for (int i = 0; i < leftLen; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < rightLen; j++)
rightArr[j] = arr[middle + j + 1];
int l = 0, r = 0;
int k = left;
while (l < leftLen && r < rightLen) {
if (leftArr[l] <= rightArr[r]) {
arr[k] = leftArr[l];
l++;
} else {
arr[k] = rightArr[r];
r++;
}
k++;
}
//复制剩余的数组元素
while (l < leftLen) {
arr[k] = leftArr[l];
l++;
k++;
}
//复制剩余的数组元素
while (r < rightLen) {
arr[k] = rightArr[r];
r++;
k++;
}
}
}
参考资料
《算法导论》