排序演算法 歸併排序

2021-10-23 05:35:04 字數 2311 閱讀 3603

歸併排序(merge sort)是利用「歸併」技術來進行排序,所謂歸併是指將若干個子檔案合併為乙個檔案的過程,由約翰·馮·諾伊曼發明。該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。即是將檔案先分解再合併,最終得到有序序列。

題目描述

給出一組資料,根據由小到大順序輸出。

輸入要求:

輸入乙個整數n(資料長度)

輸入n個資料

輸出要求:

輸出由小到大排序後的資料

樣例輸入:

10

37 28 46 19 55 28 92 84 63 71

樣例輸出:
19 28 28 37 46 55 63 71 84 92

基本思想

假設待排序的資料都存放在陣列r[n]中,mid是陣列長度的一半,將陣列分成r[0] ~ r[mid]和r[mid+1] ~ r[n-1]兩個子檔案,用遞迴的方式繼續將這兩個子檔案再各自分解成兩部分,直至子檔案中只有1個元素,這是分解的過程。然後將兩個子檔案合併成乙個有序檔案,直至形成有序序列,這是歸併的過程。

分解的過程利用遞迴操作即可實現。而排序的重點是歸併的過程,即如何將兩個檔案合併成乙個有序序列。以本例最後一次歸併過程為例(經過前幾次歸併後,這兩個子檔案自身都是有序的),i 和 j 分別指向兩個子檔案的第乙個元素,並定義乙個臨時陣列temp,i 和 j 位置元素進行比較,將較小的放入臨時陣列,然後向右繼續比較。

當乙個子檔案內所有元素都已放入臨時陣列temp中,另乙個子檔案剩餘元素無需再比較,因為經過前面的歸併子檔案本身是有序的,直接依次放入臨時陣列中即可。

歸併結束後將臨時陣列temp中的元素在放回元陣列r中。

參考**(c語言)

#include

void

merge_sort

(int r,

int start,

int end)

;//歸併排序

void

merge

(int r,

int start,

int mid,

int end)

;//歸併過程

intmain()

void

merge

(int r,

int start,

int mid,

int end)

while

(j<=end)

//第乙個檔案元素都已放入臨時陣列

temp[k++

]=r[j++];

//將第二個檔案剩餘元素放入臨時陣列

while

(i<=mid)

//第二個檔案元素都已放入臨時陣列

temp[k++

]=r[i++];

//將第乙個檔案剩餘元素放入臨時陣列

for(i=

0;i) r[start+i]

=temp[i]

;//將臨時陣列的元素放回原陣列r中

}void

merge_sort

(int r,

int start,

int end)

}

分析總結

歸併排序和快速排序都是分治思想應用在排序中的經典例項,所謂分治即「分而治之」,就是將乙個大問題分解成若干小問題,並且小問題要具有和大問題一樣的性質,然後將小問題的解合併得到大問題的解。本例中每次歸併操作都是將兩個子檔案合併成乙個有序檔案,這種方法稱為「二路歸併排序」。類似地也可以有「三路歸併排序」或「多路歸併排序」。

利用了分治思想,所以歸併排序的效率也是比較高的,利用遞迴需進行(log

2nlog_2n

log2​n

)趟歸併,每趟歸併花費時間是o(n

nn),所以歸併排序最好和最壞情況下的時間複雜度均是o(nlo

g2nnlog _2n

nlog2​

n)。平均時間複雜度o(nlo

g2nnlog _2n

nlog2​

n)空間複雜度o(nnn)

二路歸併排序是穩定的。

寫在最後

排序演算法 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...

排序演算法 歸併排序

include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...

排序演算法 歸併排序

歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...