归并排序
过程:
1. 分解 分解待排序的n个元素的序列 成各具n/2个元素的两个子序列
2. 解决 使用归并排序递归地排序两个子序列
3. 合并 合并两个已排序的子序列以产生已排序的答案
注:当待排序的序列长度为1时,递归“开始回升”,在这种情况下无需做任何工作,因为长度为1的每个序列已经排好序
算法
//一次归并过程
//A为数组,p,q,r分别为数组下标 且满足 p<=q<r
//假设子数组A[p…q]和A[q+1…r]都已经排序好 合并后为A[p…r]
MERGE(A,p,q,r)
n1=q-q+1
n2=r-q
let L[1…n1+1]和 R[1…n2]为新的数组
for i=1 to n1
L[i]=A[p+i-1]
for j=1 to n2
R[j]=A[q+j]
L[n1+1]为无穷大
R[n2+1]为无穷大
i=1
j=1
for k=p to r
if L[i] <= R[j]
A[k]=L[i]
i=i+1
else
A[k] = R[j]
j=j+1
//归并排序
MERGE-SORT(A,p,r)
if(p < r)
q=(p+r)/2
MERGE-SORT(p,q)
MERGE-SORT(q+1,r)
MERGE(p,q,r)
算法复杂度
最好、最坏和平均:nlgn
Java实现
import java.util.Random;
public class Main{
private static int N = 10;
static Random rand = new Random();
public static void main(String[] args) {
// TODO Auto-generated method stub
test_Merge_ASC();
test_Merge_DES();
}
// 测试排序
private static void test_Merge_ASC() {
int[] A = new int[N];
for (int i = 0; i < N; i++) {
A[i] = rand.nextInt(1000);
}
System.out.println("排序前:");
print(A);
Merge_Sort_ASC(A, 0, A.length - 1);
System.out.println("排序后(升序):");
print(A);
}
// 测试排序
private static void test_Merge_DES() {
int[] A = new int[N];
for (int i = 0; i < N; i++) {
A[i] = rand.nextInt(1000);
}
System.out.println("排序前:");
print(A);
Merge_Sort_DES(A, 0, A.length - 1);
System.out.println("排序后(降序):");
print(A);
}
// 归并排序 升序
private static void Merge_Sort_ASC(int[] A, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
Merge_Sort_ASC(A, p, q);
Merge_Sort_ASC(A, q + 1, r);
Merge_ASC(A, p, q, r);
}
}
// 归并过程 升序
private static void Merge_ASC(int[] A, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
// 为左右创建两个新数组
int[] L = new int[n1 + 1];
int[] R = new int[n2 + 1];
// 为新数组赋值
for (int i = 0; i < n1; i++) {
L[i] = A[p + i];
}
for (int i = 0; i < n2; i++) {
R[i] = A[q + 1 + i];
}
L[n1] = Integer.MAX_VALUE;
R[n2] = Integer.MAX_VALUE;
// 对比 归并
int i = 0;
int j = 0;
for (int k = p; k <= r; k++) {
if (L[i] <= R[j]) {
A[k] = L[i];
i = i + 1;
} else {
A[k] = R[j];
j = j + 1;
}
}
}
// 归并排序 降序
private static void Merge_Sort_DES(int[] A, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
Merge_Sort_DES(A, p, q);
Merge_Sort_DES(A, q + 1, r);
Merge_DES(A, p, q, r);
}
}
// 归并过程 降序
private static void Merge_DES(int[] A, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
// 为左右创建两个新数组
int[] L = new int[n1 + 1];
int[] R = new int[n2 + 1];
// 为新数组赋值
for (int i = 0; i < n1; i++) {
L[i] = A[p + i];
}
for (int i = 0; i < n2; i++) {
R[i] = A[q + 1 + i];
}
L[n1] = Integer.MIN_VALUE;
R[n2] = Integer.MIN_VALUE;
// 对比 归并
int i = 0;
int j = 0;
for (int k = p; k <= r; k++) {
if (L[i] > R[j]) {
A[k] = L[i];
i = i + 1;
} else {
A[k] = R[j];
j = j + 1;
}
}
}
// 打印数组
private static void print(int[] A) {
// TODO Auto-generated method stub
for (int i = 0; i < A.length; i++) {
System.out.print(A[i] + "\t");
}
System.out.println();
}
}
结果截图: