分治法:将原问题划分成n个规模较小而结构与原问题相似的子问题,递归的解决这些子问题,然后再合并其结果,就得到原问题的解。
步骤:分解-》解决-》合并。
归并排序算法分析:
这里我们有一个长度为8的数组,元素为{3,1,5,2,4,99,88,7};
1、分解,把原数组划分成n个相似的子问题,划分结果如图所示:
2、解决子问题:对每个小的数组进行合并,即(1,3)(2,5)(4,99)(7,8)
3、合并子问题:(1,2,3,5)(4,7,8,99)–》(1,2,3,4,5,7,8,99)**
时间复杂度分析:
N 为数组长度,N = 1是,T(N) = C; (C代表规模为1的问题所需时间)
分解子问题复杂度为:T(N) = 2T(N/2) + CN = 2NlgN + CN = NlgN(N > 1)
算法稳定性:稳定
#include <iostream>
using namespace std;
void MergeSort(int* A, int lIndex, int rIndex);
void Merge(int* A, int lIndex, int mIndex, int rIndex);
int main ()
{
int arr[] = {3,1,5,2,4,99,8,7};
int len = sizeof(arr)/sizeof(int);
MergeSort(arr, 0, len-1);
for (int i = 0; i < len; ++i)
{
cout << arr[i] << "\t";
}
cout << endl;
return 0;
}
void MergeSort(int* A, int lIndex, int rIndex)
{
if (A == NULL || lIndex >= rIndex)
{
return;
}
int midIndex = (lIndex + rIndex) / 2;
MergeSort(A, lIndex,midIndex);
MergeSort(A, midIndex+1, rIndex);
Merge(A, lIndex, midIndex, rIndex);
}
void Merge(int* A, int lIndex, int mIndex, int rIndex)
{
if (A == NULL || lIndex > mIndex || mIndex > rIndex)
{
return;
}
int iLengthL = mIndex - lIndex + 1;
int* L = new int[iLengthL];
for (int i = 0; i < iLengthL; ++i)
{
L[i] = A[lIndex + i];
}
int iLengthR = rIndex - mIndex;
int* R = new int[iLengthR];
for (int i = 0; i < iLengthR; ++i)
{
R[i] = A[mIndex + i + 1];
}
int startL = 0;
int startR = 0;
int startA = lIndex;
while (1)
{
if (L[startL] <= R[startR])
{
A[startA++] = L[startL++];
if (startL == iLengthL)
{
break;
}
}
else
{
A[startA++] = R[startR++];
if (startR == iLengthR)
{
break;
}
}
}
while (startL != iLengthL)
{
A[startA++] = L[startL++];
}
while(startR != iLengthR)
{
A[startA++] = R[startR++];
}
delete L;
delete R;
}
代码实现2
void Merge(int arr[], int fromIndex1, int endIndex1, int fromIndex2, int endIndex2)
{
int* tmparr = new int[endIndex2 - fromIndex1 + 1];
int i = fromIndex1, j = fromIndex2, k = 0;
while(i <= endIndex1 && j <= endIndex2)
{
if (arr[i] <= arr[j])
{
tmparr[k++] = arr[i++];
}
else {
tmparr[k++] = arr[j++];
}
}
int startIndex = i;
int endIndex = endIndex1;
if (j < endIndex2)
{
startIndex = j;
endIndex = endIndex2;
}
while (startIndex <= endIndex)
{
tmparr[k++] = arr[startIndex++];
}
startIndex = fromIndex1;
for (int i = 0; i < k; ++i)
{
arr[startIndex++] = tmparr[i];
}
delete[] tmparr;
}
void MergeSort(int arr[], int beginIndex, int endIndex)
{
if (beginIndex >= endIndex)
{
return;
}
int q = beginIndex + (endIndex - beginIndex) / 2;
MergeSort(arr, beginIndex, q);
MergeSort(arr, q + 1, endIndex);
Merge(arr, beginIndex, q, q + 1, endIndex);
}