逝者如斯夫,不捨晝夜
歸併排序是一種非常快的排序算法。該算法的核心思想是分治。通過將一個較大的序列分解成多個較小的序列進行處理,最後再進行合併,從而完成排序。
實現歸併排序的關鍵是如何完成合並,以及如何分解序列,同時要注意用於判斷序列是否結束時使用的”哨兵”。
C++實現示例:
void merge(int* A, int m, int k, int n)
{
int* A1 = new int[k - m + 1 + 1];
int* A2 = new int[n - k + 1];
memcpy_s(A1, sizeof(int) * (k - m + 1), A + m, sizeof(int) * (k - m + 1));
memcpy_s(A2, sizeof(int) * (n - k), A + k + 1, sizeof(int) * (n - k));
// Sentinel
A1[k - m + 1] = 0xFFFF;
A2[n - k] = 0xFFFF;
int i = 0;
int j = 0;
int x = m;
while (i < k - m + 1 || j < n - k)
{
if (A1[i] < A2[j])
{
A[x] = A1[i];
i++;
}
else
{
A[x] = A2[j];
j++;
}
x++;
}
}
void mergesort(int* A, int m, int n)
{
if (m >= n)
{
return;
}
int q = (m + n) / 2;
mergesort(A, m, q);
mergesort(A, q + 1, n);
merge(A, m, q, n);
}
int main()
{
int A[] = { 109, 24, 51, 7, 1, 15, 33, 20, 12, 67, 0 };
mergesort(A, 0, 10);
for (int i = 0; i < 11; i++)
{
cout << A[i] << endl;
}
return 0;
}
Java實現示例:
public static void main(String[] args) {
int A[] = { 109, 24, 51, 7, 1, 15, 33, 20, 12, 67, 0 };
mergesort(A, 0, 10);
for (int a : A) {
System.out.println(a);
}
}
public static void merge(int[] A, int m, int k, int n) {
int[] a1 = new int[k - m + 1 + 1];
int[] a2 = new int[n - k + 1];
System.arraycopy(A, m, a1, 0, k - m + 1);
System.arraycopy(A, k + 1, a2, 0, n - k);
// Sentinel
a1[k - m + 1] = 0xFFFF;
a2[n - k] = 0xFFFF;
int i = 0;
int j = 0;
int x = m;
while (i < k - m + 1 || j < n - k) {
if (a1[i] < a2[j]) {
A[x] = a1[i];
i++;
}
else {
A[x] = a2[j];
j++;
}
x++;
}
}
public static void mergesort(int[] A, int m, int n) {
if (m >= n) {
return;
}
int q = (m + n) / 2;
mergesort(A, m, q);
mergesort(A, q + 1, n);
merge(A, m, q, n);
}