众所周知,Mergesort是一种分而治之的算法,它将数组递归地分成两半,直到达到大小为1的数组为止,然后合并排序后的子数组,直到对原始数组进行完全排序为止。在所有三种情况下(最佳,平均和最差),合并排序的典型实现都在O(n Log n)时间中进行。
我们需要将最佳情况下的性能从O(n log n)降低到O(n)。
想法是考虑数组已经排序的情况。合并之前,只需检查arr [mid]> arr [mid + 1],因为我们正在处理排序的子数组。这将导致我们得到递归关系T(n)= 2 * T(n / 2)+1,可以通过母定理来求解,因此T(n)= n。
例子:
Input : 1 2 3 4
Subarrays with size of 1:|1||2| |3||4|
Subarrays with size of 2: |1 2| |3 4|
Output : 1 2 3 4
Input : 1 2 3 4 5 6 7 8
Subarrays with size of 1: |1||2| |3||4| |5||6| |7||8|
Subarrays with size of 2: |1 2| |3 4| |5 6| |7 8|
Subarrays with size of 4: |1 2 3 4| |5 6 7 8|
Output : 1 2 3 4 5 6 7 8
// C program to implement merge sort that works
// in O(n) time in best case.
#include
#include
void merge(int* arr, int low, int mid, int high);
void mergesort(int* arr, int low, int high)
{
if (low < high) {
int mid = (low + high) / 2;
mergesort(arr, low, mid);
mergesort(arr, mid + 1, high);
// This is where we optimize for best
// case.
if (arr[mid] > arr[mid + 1])
merge(arr, low, mid, high);
}
}
void merge(int* arr, int low, int mid, int high)
{
int i = low, j = mid + 1, k = 0;
int* temp = (int*)calloc(high - low + 1, sizeof(int));
while ((i <= mid) && (j <= high))
if (arr[i] < arr[j])
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
while (j <= high) // if( i>mid )
temp[k++] = arr[j++];
while (i <= mid) // j>high
temp[k++] = arr[i++];
// copy temp[] to arr[]
for (i = low, k = 0; i <= high; i++, k++)
arr[i] = temp[k];
free(temp);
}
int main()
{
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
mergesort(a, 0, 7);
for (int i = 0; i < 8; i++)
printf("%d ", a[i]);
return 0;
}
输出:
1 2 3 4 5 6 7 8