归并排序(Merge Sort) C语言实现
归并排序(mergesort)构思朴实而深刻,作为一个算法即古老又仍不失生命力。在排序算法的发展历史上,归并排序具有特殊的历史地位,它是第一个可以在最坏情况下依然保持**O(nlogn)**运行时间的确定性排序算法。
无序向量的递归分解+有序向量的逐层合并(二路归并算法)。
1. int 类型 mergesort
// 对arr中的[lo, hi) 进行归并排序
void mergesort(int arr[], int lo, int hi)
{
if(hi-lo<2) // 单元素自然有序
return;
int mi = (lo+hi)>>1; // 将arr均等分成两部分[lo, mi), [mi,hi)
mergesort(arr, lo, mi); // 对arr[lo, mi) 进行排序
mergesort(arr+mi, 0, hi-mi ); // 对arr[mi, hi) 进行排序
merge(arr, lo, mi, hi); // 二路归并算法
}
// 二路归并算法
void merge(int arr[], int lo, int mi, int hi)
{
int * A= malloc(sizeof(int)*(mi-lo)); // 为了将排序好的arr返回,需要申请临时空间
memcpy(A, arr, sizeof(int)*(mi-lo)); // 将arr前半部分复制到A中
int * B= arr; // B亦指向arr中第一个元素的地址
int i=lo, j=lo, k=mi;
while( j<mi || k<hi) // 循环条件
{
if((j<mi) && (!(k<hi) || A[j] <= B[k]))
{
arr[i++] = A[j++];
}
if((k<hi) && (!(i<mi) || A[j]> B[k]))
{
arr[i++] = B[k++];
}
}
free(A);
}
/*
(!(k<hi) ||A[j] <B[k]) 等价于
k==hi || k<hi && A[j] < B[k] (短路法则)
为了保证算法的正确性,在循环中应该满足
k<=hi && j<mi;或者
j<=mi && k<hi;或者
j<mi && k<hi
当满足k==hi && j==mi 时退出循环。
*/
2. C泛型实现
- mergesort.h
#pragma once