排序算法-合併排序

說明

      之前所介紹的排序法都是在同一個陣列中的排序,考慮今日有兩筆或兩筆以上的資料,它可能是不同陣列中的資料,或是不同檔案中的資料,如何爲它們進行排序?
解法

      可以使用合併排序法,合併排序法基本是將兩筆已排序的資料合併並進行排序,如果所讀入的資料尚未排序,可以先利用其它的排序方式來處理這兩筆資料,然後再將排序好的這兩筆資料合併。有人問道,如果兩筆資料本身就無排序順序,何不將所有的資料讀入,再一次進行排序?排序的精神是儘量利用資料已排序的部份,來加快排序的效率,小筆資料的排序較爲快速,如果小筆資料排序完成之後,再合併處理時,因爲兩筆資料都有排序了,所有在合併排序時會比單純讀入所有的資料再一次排序來的有效率。
      那麼可不可以直接使用合併排序法本身來處理整個排序的動作?而不動用到其它的排序方式?
      答案是肯定的,只要將所有的數字不斷的分爲兩個等分,直到最後剩一個數字爲止,然後再反過來不斷的合併,就如下圖所示:

 

      不過基本上分割又會花去額外的時間,不如使用其它較好的排序法來排序小筆資料,再使用合併排序來的有效率。下面的程序範例,使用的是快速排序法來處理小筆資料排序,然後再使用合併排序法處理合並的動作。  

      代碼:

//這個快速排序法的概念,它以最右邊的值s作比較的標準,將整個數列分爲三個部份,
//一個是小於s的部份,一個是大於s的部份,一個是未處理的部份

int partition(int number[],int left, int right) //尋找軸所在的正確位置
{
	int i,j,s;
	int temp;
	s = number[right];
	i = left - 1;
	j = left;
	for(j=left;j<right;++j)
	{
		if(number[j] <= s)
		{
			++i;
			temp = number[i];
			number[i] = number[j];
			number[j] = temp;
		}
	}
	temp = number[i+1];
	number[i+1] = number[right];
	number[right] = temp;

	return i+1;
}

void quicksort3(int number[], int left, int right)
{
	int q;
	if(left < right)
	{
		q = partition(number,left,right);
		quicksort3(number,left,q-1);
		quicksort3(number,q+1,right);
	}
}

//合併排序,各獨立文件採用快速排序排好序
void mergesort(int number1[],int M,int number2[],int N,int number3[])
{
	int i,j,k;
	i = 0; j = 0; k = 0;
	while(i < M && j < N)
	{
		if(number1[i] <= number2[j])
			number3[k++] = number1[i++];
		else
			number3[k++] = number2[j++];
	}
	while(i < M)
		number3[k++] = number1[i++];
	while(j < N)
		number3[k++] = number2[j++];
}


 

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