归并排序,也是很快的!
归并排序:
两个已排序数组的归并操作:每次从两个数组头部取出最小(或最大)的一个元素,出队,加入新数组末端,直到取完,得到由两个已排序数组元素组成的一个新的已排序数组。
把一个未排序数组不断分割,看成许多单元素组成的数组(可以作为有序的),然后不断归并,最后得到一个排序过的数组。这就是归并排序。
O(nlog(n))的时间复杂度,和快排、堆排一样。不过归并排序总是需要额外的空间存储新数组,所以不如快排的。其优点是没有特别糟的情况,最坏时间复杂度还是那么多。
用C语言写了个递归实现的,gcc 4.5.2,归并排序效率和标准库的qsort()差不多,略快一些(20000000随机数:qsort() 4.06s 归并排序 3.98s),还是相当不错的排序算法。感觉递归可以消去,可能再快一些。
void MergeSort (int *a, const int len)
{
if (len > 2)
{
MergeSort (a, len/2);
MergeSort (a+len/2, len-len/2);
int *buf = malloc( len * sizeof(int) );
int i, *p1 = a, *p2 = a+len/2;
for (i=0; i<len-1 && p1!=a+len/2 && p2!=a+len; i++)
if (*p1 < *p2)
buf[i] = *p1++;
else
buf[i] = *p2++;
if (p1 != a+len/2)
memcpy(buf+i, p1, (len-i)*sizeof(int));
else if (p2 != a+len)
memcpy(buf+i, p2, (len-i)*sizeof(int));
memcpy(a, buf, len*sizeof(int));
free(buf);
}
else if (len == 2 && a[0] > a[1])
{
int temp = a[0];
a[0] = a[1];
a[1] = temp;
}
}