上次一个题让写一种稳定的排序算法,就是归并排序咯,然而不会,谨以此记住
归并排序:
时间复杂度 n*log(2) n , 状态 稳定 辅助空间 O(n)
典型的一种二分策略的排序,整个过程分为两步
1. 二分,把待排序数组分成两部分,再二分,直到只剩一个元素为止;
2.合并,每次把两个数组按照从小到大的顺序合并,每一次合并的过程就会有一部分元素变成有序的,
3.分治策略很重要
一个不算精简的代码:
void merge(int* src, int* des, int low,int mid, int high) //合并
{
int i=low;
int j=mid+1;
int k=low;
while((i<=mid)&&(j<=high))
{
if(src[i]<src[j])
{
des[k++] = src[i++];
}
else
{
des[k++] = src[j++];
}
}
while(i<=mid)
{
des[k++] = src[i++];
}
while(j<=high)
{
des[k++] = src[j++];
}
}
void devide(int* src, int* des, int low, int high, int max) //二分
{
if(low == high) //只剩一个元素,递归划分结束,开始合并
{
des[low] = src[low];
}
else
{ //递归的进行两路划分
int mid = (low + high) / 2;
int* tmp = (int *)malloc(sizeof(int)* max);
if(tmp != NULL)
{
devide(src, tmp, low, mid, max);
devide(src, tmp, mid+1, high, max);
merge(tmp, des, low, mid, high);
}
free(tmp);
}
}
void merge_sort(int* src, int length)
{
devide(src, src, 0, length-1, length);
}
顺便改成模板函数
template <typename T>
void merge(T* src, T * des, int low, int mid, int high) //归并
{
int i = low;
int j = mid + 1;
int k = low;
while ((i <= mid) && (j <= high)) //将小的放到目的数组中
{
if (src[i] < src[j]) //那个临时数组
{
des[k++] = src[i++];
}
else
{
des[k++] = src[j++];
}
}
while (i <= mid) //若还剩几个尾部元素
{
des[k++] = src[i++];
}
while (j <= high) //若还剩几个尾部元素
{
des[k++] = src[j++];
}
}
//每次分为两路 当只剩下一个元素时,就不需要在划分
template <typename T>
void devide(T *src, T* des, int low, int high, int max) //划分
{
if (low == high) //只剩一个元素时,直接赋值给des
{
des[low] = src[low];
}
else
{
int mid = (low + high) / 2;
T* tmp = (T*)malloc(sizeof(T)*max);
//递归进行两路,两路的划分
//当剩下一个元素的时,递归划分结束,然后开始merge归并操作
if (tmp != NULL)
{
devide(src, tmp, low, mid, max);
devide(src, tmp, mid + 1, high, max);
merge(tmp, des, low, mid, high); //调用归并函数进行归并
}
free(tmp);
}
}
template <typename T>
void mergesort(T* src, int len)
{
devide(src, src, 0, len - 1, len);
}
也可以改成对指针进行存储,然后交换指针,,,,未完