印象中,当年我的老师是很强调归并算法的,处处涉及它。那时候年轻,不胜理解。今天,我把排序相关的内容温故一遍后,才有感同身受!!!
归并算法除了能达到最优秀的O(nlog2n)的时间复杂度外,它比快速算法强在于没有意外的情况(快速算法最快能达到O(nlogn)),除了要多提供一个同量的附加占用空间外,它真实没毛病了。对于如今的大内存计算机而言,它就是完美的啊。所以,以后的排序问题,我都打算用归并来解决了。
——————————————————————————————————————————————
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void merge(int arr1[], int arr2[], int left, int mid, int right)
{
int i = left, j = mid+1, k = left;
while (i<=mid&&j<=right)
{
if (arr1[i]<=arr1[j])
{
arr2[k++] = arr1[i++];
}
else
{
arr2[k++] = arr1[j++];
}
}
while (i<=mid)
{
arr2[k++] = arr1[i++];
}
while (j<=right)
{
arr2[k++] = arr1[j++];
}
}
void mergepass(int arr1[], int arr2[], int length, int len)
{
int i = 0;
while (i+2*len<=length)
{
merge(arr1, arr2, i, i+len-1, i+2*len-1);
i = i+2*len;
}
if (i+len<=length-1)
{
merge(arr1, arr2, i, i+len-1, length-1);
}
else
{
for (int j=i; j<length; j++)
{
arr2[j] = arr1[j];
}
}
}
void mergesort_iter(int arr[], int length)
{
int *arr1 = (int*)malloc(length*sizeof(int));
int len = 1;
if (arr1)
{
while (len<length)
{
mergepass(arr, arr1, length, len);
len *= 2;
mergepass(arr1, arr, length, len);
len *= 2;
}
free(arr1);
}
}
void main()
{
int arr[] = {88, 1, 7, 9, 2, 4,3, 7, 5, 22, 77, 56, 34, 23, 55, 66, 98, 89};
int len = sizeof(arr)/sizeof(int);
mergesort_iter(arr, len);
for (int i=0; i<len; i++)
{
printf("%d ", arr[i]);
}
printf(" ");
}
// result
# ./sort
1 2 3 4 5 7 7 9 22 23 34 55 56 66 77 88 89 98
Finally:
时代在发展,思想得更新!