merge_sort

上次一個題讓寫一種穩定的排序算法,就是歸併排序咯,然而不會,謹以此記住

歸併排序:

時間複雜度 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);
}


然而發現並沒有什麼卵 用, 因爲歸併所用到的輔助空間太大,對於對象之間的排序,光是進行內存分配,和對象拷貝,都不划算,

也可以改成對指針進行存儲,然後交換指針,,,,未完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章