归并排序
归并排序运用的是分治的思想,将问题分解成规模更加小的问题解决,然后合并。归并排序先将待排序序列分解成更加小的待排序序列直到待排序序列已经排好序(长度为1),然后合并排好序的序列。
涉及算法的伪代码实现
// 使用一个哨兵避免每次都判断待排序序列越界问题
MEARGE(A, lo, mid, hi)
n1 = mid - lo + 1;
n2 = hi - mid;
let L[1..n1+1] AND R[1..n2+1] to be new array
for i = 1 to n1
L[i] = A[i + lo -1]
for j = 1 to n2
R[j] = A[j + mid]
L[n1 + 1] = ∞
R[n2 + 1] = ∞
i = 1
j = 1
for k = lo to hi
if (L[i] < R[j])
A[k] = L[i]
i = i + 1
else
A[K] = R[j]
j = j + 1
//不使用哨兵实现归并
MEARGE(A, lo, mid, hi)
n1 = mid - lo + 1
n2 = hi - mid
let L[1..n1] AND R[1..n2] to be new array
for i = 1 to n1
L[i] = A[i + lo - 1]
for j = 1 to n2
R[j] = A[mid + j]
i = 1
j = 1
for(k = lo;k <= hi; k++)
if (i > mid)
A[k] = R[j]
j = j + 1
else if j > hi
A[k] = L[i]
i = i + 1
else if L[i] < R[j]
A[k] = L[i]
i = i + 1
else
A[k] = R[j]
j = j + 1
以上算法都是将数组分成左右两个子数组,直到分界到数组元素只有1个。中间会产生n + n/2 + n/4…个临时的空间。改善如下
TEMP = A // 深复制,通过TEMP实现分成两部分查找
MEARGE(A, lo, min, hi)
i = lo, j = mid + 1;
for(k = 0; k <= hi; i++)
if(i > mid)
A[k] = TEMP[j]
j = j + 1
else if (j > hi)
A[k] = TEMP[i]
i = i + 1
else if (TEMP[i] > TMEP[j])
A[K] = TEMP[j]
j = j + 1
else
A[k] = TEMP[i]
i = i + 1
MEARGE-SORT(A, lo, hi)
if (lo > hi)
return
mid = lo + (hi - lo)/2
MEARGE-SORT(A, lo, mid)
MEARGE-SORT(A, mid + 1, hi)
MEARGE(A, lo, mid, hi)
Java 实现
public class MeargeSort {
static Integer[] temp = null;
public static void main(String[] args) {
Integer[] a = { 2, 5, 4, 3, 6, 8, 7, 6 };
temp = new Integer[a.length];
sort(a, 0, a.length - 1);
for (Integer item : a)
System.out.print(item + " ");
}
public static void mearge(Integer[] a, int lo, int mid, int hi) {
for (int i = lo; i <= hi; i++)
temp[i] = a[i];
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid)
a[k] = temp[j++];
else if (j > hi)
a[k] = temp[i++];
else if (temp[i] < temp[j]) {
a[k] =temp[i];
i++;
} else {
a[k] = temp[j];
j++;
}
}
}
public static void sort(Integer[] a, int lo, int hi) {
if (lo >= hi)
return;
int mid = lo + (hi - lo) / 2;
sort(a, lo, mid);
sort(a, mid + 1, hi);
mearge(a, lo, mid, hi);
}
}
性能
时间复杂度:O( nlogn ) / 空间复杂度:O(n) (关于分析步骤 TODO)