歸并算法(MERGE-SORT)(設(shè)按升序排列)
1、分冶法---分冶思想的介紹
將原始問題分解為幾個(gè)規(guī)模較小但類似于原問題容易解決的子問題,遞歸地求解這些子問題,然后再合并子問題的解來建立原始問題的解。
分冶法在遞歸時(shí)的步驟
分解: 原問題分解為子問題,子問題是原問題規(guī)模較小的實(shí)例。
解決: 遞歸地解決子問題,若子問題足夠小,則直接求解。
合并: 合并子問題的解。得到原問題解。
在歸并排序中的體現(xiàn)
分解: 分解待排序的n個(gè)元素的序列成各自具有n/2個(gè)元素的兩個(gè)子序列。
解決: 使用歸并排序遞歸地排序兩個(gè)子序列。
合并: 合并兩個(gè)已排序的子序列一產(chǎn)生最終已排序的序列。
2、 歸并排序偽代碼描述
主過程: MERGE-SORT(A, startIndex, endIndex), A: 待排數(shù)組 startIndex: 起始數(shù)組下標(biāo) endIndex: 截止數(shù)組下標(biāo)
MERGE-SORT(A, startIndex, endIndex)
if startIndex < endIndex
midIndex = (startIndex + endIndex)/2 // midIndex取(startIndex + endIndex)/2值的底;
MERGE-SORT(A, startIndex ,midIndex)
MERGE-SORT(A, midIndex + 1,endIndex)
MERGE(A, startIndex, midIndex, endIndex)
子過程: MERGE(A, startIndex, midIndex, endIndex)
MERGE(A, startIndex, midIndex, endIndex)
n1 = midindex - startIndex + 1
n2 = endIndex - midIndex
let L[1..n1+1] and R[1..n2+1] be new arrays
for i = 1 to n1
L[i] = A[startIndex + i -1]
for j = 1 to n2
R[j] = A[midIndex + j]
L[n1+1] = Infinity
R[n2+1] = Infinity
i = 1
j = 1
for k = startIndex to endIndex
if L[i] <= R[j]
A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1
C#代碼
static void Merge<T>(T[] arr, int left, int middle, int right) where T: IComparable<T>
{
T[] leftArray = new T[middle - left + 1];
T[] rightArray = new T[right - middle];
Array.Copy(arr, left, leftArray, 0, middle - left + 1);
Array.Copy(arr, middle + 1, rightArray, 0, right - middle);
int i = 0;
int j = 0;
for (int k = left; k < right + 1; k++)
{
if (i == leftArray.Length)
{
arr[k] = rightArray[j];
j++;
}
else if (j == rightArray.Length)
{
arr[k] = leftArray[i];
i++;
}
else if (leftArray[i].CompareTo(rightArray[j]) <= 0)
{
arr[k] = leftArray[i];
i++;
}
else
{
arr[k] = rightArray[j];
j++;
}
}
}
static void MergeSort<T>(T[] arr, int left, int high) where T: IComparable<T>
{
if (left< high)
{
int mid = (left + high) / 2;
MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, high);
Merge(arr, left, mid, high);
}
}