上次一個題讓寫一種穩定的排序算法,就是歸併排序咯,然而不會,謹以此記住
歸併排序:
時間複雜度 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);
}
也可以改成對指針進行存儲,然後交換指針,,,,未完