1. 程式人生 > >歸併排序的遞迴實現(C語言)

歸併排序的遞迴實現(C語言)

前言:

理論很枯燥、文字更煩人,但是這裡將理論知識告訴大家並不是讓大家一上來就看乾巴巴的文字,因為我在程式碼中能註釋的地方都進行了註釋希望大家先跟著註釋打一遍,不要著急,當在黑色的星空中出現了結果,你就會為之振奮,有了繼續學下去的勇氣,當你對程式碼中的思想有了較深的理解後,再回過頭來看這些理論文字,我相信會好很多,最後一句話:書讀百遍,其義自見。

歸併排序:

1.歸併排序(merge sorting)簡單地將原始序列劃分為兩個子序列,然後分別對每個子序列遞迴排序,最後再將有序子序列合併。歸併排序主要步驟為(1)將序列劃分為兩個子序列。(2)分別對這兩個子序列遞迴進行歸併排序。(3)將這兩個已排好序的子序列合併為一個有序序列,即歸併過程。
2.歸併排序也是一種基於分治法的排序。快速排序側重於“分”(含“治”),即用軸值分割子序列的過程,沒有明顯的“合”。歸併排序的“分”很簡單,就是攔腰折斷,一分兩半,它更多的側重的是“治”和“合”。3.歸併排序中的“治”和“合”- 兩個有序子序列的歸併:每次比較子序列頭,取出較小的進入序列;其後次小記錄頂上來,繼續比較兩個子序列頭,取出較小的進入結果序列;重複上述過程,直到其中一個子序列為空,剩餘子序列中的記錄就可以直接進入結果序列。4.歸併排序中的分 - 不斷的將原始序列分為越來越多的子序列,直到子序列長度為1,停止劃分

完整程式碼如下:(遞迴實現歸併排序)

//#pragma once
//MergeSort - 歸併排序(分治思想)

#include <iostream>
using namespace std;

//有序子列的歸併 - 治
//A - 待排陣列、TmpA - 臨時陣列、L - 左邊起始位置、R - 左邊起始位置、RightEnd - 左邊終點位置
void Merge(int A[], int TmpA[], int L, int R, int RightEnd)
{
	int LeftEnd, ElementNum, Tmp;
	LeftEnd = R - 1;  //左邊終點位置
	Tmp = L;  //歸併後陣列的起始位置
	ElementNum = RightEnd - L + 1;  //元素個數

	//歸併過程
	while (L <= LeftEnd && R <= RightEnd)
	{
		if (A[L] <= A[R])
			TmpA[Tmp++] = A[L++];
		else
			TmpA[Tmp++] = A[R++];
	}
	//解決有剩餘元素的子列
	while (L <= LeftEnd)
		TmpA[Tmp++] = A[L++];
	while (R <= RightEnd)
		TmpA[Tmp++] = A[R++];

	//將臨時陣列中排好序後的元素重新賦值給原陣列A 
	for (int i = 0; i < ElementNum; i++, RightEnd--)
		A[RightEnd] = TmpA[RightEnd];
}

//採用遞迴函式的方式實現 - 分
//A - 待排陣列、TmpA - 臨時陣列、L - 陣列左邊起始位置、RightEnd - 原陣列左邊終點位置
void Msort(int A[], int TmpA[], int L, int RightEnd)
{
	int Center;

	if (L < RightEnd)  // ==是隻剩一個元素,不需要再分
	{
		//分
		Center = (L + RightEnd) / 2;
		Msort(A, TmpA, L, Center);
		Msort(A, TmpA, Center + 1, RightEnd);
		//治
		Merge(A, TmpA, L, Center + 1, RightEnd);
	}
}

//為歸併排序函式設定統一介面
void MergeSort(int A[], int N)
{
	int *TmpA;  //臨時陣列
	TmpA = new int[N];

	if (TmpA)
	{
		Msort(A, TmpA, 0, N - 1);
		delete[] TmpA;
	}
	else
		cout << "空間不足" << endl;
}

int main()
{
	int N, i;
	//待排元素個數 
	cin >> N;
	
	int A[N];
	//輸入 
	for(i = 0; i < N; i++)
	{
		cin >> A[i];
	}
	//歸併排序 
	MergeSort(A,N);
	//輸出結果 
	for(i=0;i < N; i++)
	{
		cout << A[i] << " ";
	}
	cout << endl;
	
	return 0;
} 

執行結果: