C語言排序算法--歸併排序原理解析

歸併排序

1.實現原理

  • 下面倆介紹有一種非常有效的排序方法—歸併排序。歸併排序也採用了和快速排序一樣的分治法,也是分治法的一個非誠典型的應用。它將已經排序好的表排序成一個表。

  • 基本思路:假設有兩個子序列(相當於輸入序列)放在同一個系列中相鄰的位置上:array[low,m],array[m+1,high],先將他們合併到一個比較簡單的序列temp,複製回array[low,high],從而完成排序。

    在具體的合併過程中,設置 i,j 和 p 三個指針,其初值分別指向這三個記錄區的起始位置。合併時依次比較 array[i] 和 array[j] 的關鍵字,取關鍵字較小(或較大)的記錄複製到 temp[p] 中,然後將被複制記錄的指針 i 或 j 加 1,以及指向複製位置的指針 p加 1。重複這一過程直至兩個輸入的子序列有一個已全部複製完畢(不妨稱其爲空),此時將另一非空的子序列中剩餘記錄依次複製到 array 中即可。

    若將兩個有序表合併成一個有序表,稱爲2-路歸併。

    舉個列子:

    假設有數組int a[] = {-1,14,12,13,11,16};-1下標爲0的位置,我們不參與排序。有效元素的個數爲5個。假設我們有一個沒有排好序的序列,那麼首先我們使用分割的辦法將這個序列分割成一個個已經排好序的子序列。然後再利用歸併的方法將一個個的子序列合併成排序好的序列。分割和歸併的過程可以看下面的圖例。

在這裏插入圖片描述

2. 實現源碼分析

#define MAX 6
int sr[ ] = {-1,14,12,15,13,11,16};
int tr1[7] = {0}msort(sr,tr1,1,6);

void msort(int sr[],int tr1[],int s,int t)
{
	int m;
	int TR2[MAX + 1]; //下標爲0的位置不填充數據
	if(s == t)
	{
		TR1[s] = SR[s];	
	}else{
	m = (s + t) / 2;
	Msort(SR,TR2,s,m);  //把數組分爲1-m左邊的部分
	Msort(SR,TR2,m + 1,t); //把數組分爲m + 1 –t右邊的部分
	Merge(TR2,TR1,s,m,t); //對劃分好的組進行排序。
	}
}

void merge(int sr[],int tr[],int i,int m,int n)
{
	int j,k,l;
    //找到較小的填充到tr數組中
	for(j = m + 1,k = i;i <= m && j <= n;k++)
	{
		if(SR[i] < SR[j])
		{
			TR[k] = SR[i++];	
		}else{
		TR[k] = SR[j++];	
		}
	}		
	//把剩下的數據填充到tr數組中即可。
	if(i <= m)
	{
		for(l = 0;l <= m - i;l++)
		{
			TR[k + 1] = SR[i + l];	
		}
	}
				
	if(j <= n)
	{
		for(l = 0;l <= n - j;l++)
		{
			TR[k + l] = SR[i + l];	
		}
	}
}

3.總結

  • 歸併排序主要分爲兩個步驟,使用到了分治法的思想,在程序實現上也用到了遞歸的方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章