歸併排序(merge-sort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。
過程描述:
歸併過程為:比較a[i]和b[j]的大小,若a[i]≤b[j],則將第乙個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素b[j]複製到r[k]中,並令j和k分別加上1,如此迴圈下去,直到其中乙個有序表取完,然後再將另乙個有序表中剩餘的元素複製到r中從下標k到下標t的單元。歸併排序的演算法我們通常用遞迴實現,先把待排序區間[s,t]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]
評價演算法:
平均時間複雜度:o(n*log(n))
原理:
歸併操作的工作原理如下:
第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列
第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
重複步驟3直到某一指標超出序列尾
將另一串行剩下的所有元素直接複製到合併序列尾
現在我有兩個已經排好順序的陣列:int arr1 =
和int arr2 =
,我還有乙個大陣列來裝載它們int arr = new int[6];
那麼,我將兩個陣列的值進行比較,誰的值比較小,誰就放入大陣列中!
首先,拿出arr1[0]
和arr2[0]
進行比較,顯然是arr2[0]
比較小,因此將arr2[0]
放入大陣列中,同時arr2
指標往後一格
所以,現在目前為止arr =
隨後,拿arr1[0]
和arr2[1]
進行比較,顯然是arr1[0]
比較小,將arr1[0]
放入大陣列中,同時arr1
指標往後一格
所以,現在目前為止arr =
隨後,拿arr1[1]
和arr2[1]
進行比較,顯然是arr2[1]
比較小,將arr2[1]
放入大陣列中,同時arr2
指標往後一格
所以,現在目前為止arr =
遍歷到最後,我們會將兩個已排好序的陣列變成乙個已排好序的陣列arr =
歸併排序的前提是需要兩個已經排好順序的陣列,那往往不會有兩個已經排好順序的陣列給我們的呀(一般是雜亂無章的乙個陣列),那這個演算法是不是很雞肋的呢??
其實並不是的,首先假設題目給出的陣列是這樣子的:int arr = ;
當我們要做歸併的時候就以arr[3]
也就元素為1的那個地方分開。是然後用乙個指標l
指向arr[0]
,乙個指標m
指向arr[3]
,用乙個指標r
指向arr[5]
(陣列最後一位)。有了指標的幫助,我們就可以將這個陣列切割成是兩個有序的陣列了(操作的方式就可以和上面一樣了)
可是上面說了,一般給出的是雜亂無章的乙個陣列,現在還是達不到要求。比如給出的是這樣乙個陣列:int arrays = ;
此時,我們就得用到分治的思想了:
那麼我們也可以這樣想將int arr = ;
陣列分隔成乙份乙份的,arr[0]
它是乙個有序的"陣列",arr[1]
它也是乙個有序的"陣列",利用指標(l,m,r)又可以像操作兩個陣列一樣進行排序。最終合成…….再不斷拆分合併,最後又回到了我們的
arr =
,因此歸併排序是可以排序雜亂無章的陣列的
public static void main(string args) ;
mergesort(arrays, 0, arrays.length - 1);
}/**
* 歸併排序
** @param arrays
* @param l 指向陣列第乙個元素
* @param r 指向陣列最後乙個元素
*/public static void mergesort(int arrays, int l, int r) else
}/**
* 合併陣列
** @param arrays
* @param l 指向陣列第乙個元素
* @param m 指向陣列分隔的元素
* @param r 指向陣列最後的元素
*/public static void merge(int arrays, int l, int m, int r)
for (int i = m; i <= r; i++)
int i = 0, j = 0;
// arrays陣列的第乙個元素
int k = l;
//比較這兩個陣列的值,哪個小,就往陣列上放
while (i < leftarray.length && j < rightarray.length) else
}//如果左邊的陣列還沒比較完,右邊的數都已經完了,那麼將左邊的數抄到大陣列中(剩下的都是大數字)
while (i < leftarray.length)
//如果右邊的陣列還沒比較完,左邊的數都已經完了,那麼將右邊的數抄到大陣列中(剩下的都是大數字)
while (j < rightarray.length)
}
歸併排序總結
歸併排序是利用分治思想,分開後一步一步歸併的過程。基本思路就是將陣列分成二組a,b,如果這二組組內的資料都是有序的,那麼就可以很方便的將這二組資料進行排序。可以將a,b組各自再分成二組。依次類推,當分出來的小組只有乙個資料時,可以認為這個小組組內已經達到了有序,然後再合併相鄰的二個小組就可以了。這樣...
歸併排序 總結
歸併排序的思想是把陣列不斷分割成兩半,然後不斷合併,具體就是先遞迴將陣列分成兩半分別排序,然後將結果歸併起來。分割的過程屬於遞迴行為,而合併過程用到了外排序的方法。外排序 用兩個指標指向兩個已排好序的陣列,申請乙個大小為n n為兩個陣列大小的和,n最大為原始陣列的大小 的陣列,把指標指向較小的數放進...
歸併排序總結
看了關於歸併排序的這篇文章之後,寫個總結 歸併排序是採用分治法的典型案例。基本思路 將陣列分成兩組 a,b,如果a,b組內的資料是有序的,那麼很容易將兩組陣列進行排序。為了將a.b兩組資料有序,那麼將a,b再分成兩組。依次類推,當分出來的小組只有乙個資料時,可以認為小組組內已經達到了有序,然後再合併...