排序演算法之歸併排序

2022-01-19 10:39:52 字數 1470 閱讀 1745

歸併排序是成功應用分治技術的乙個完美例子。

分治法的思想是:(1)將問題的例項劃分為同乙個問題的幾個較小的例項,最好擁有同樣的規模;(2)對這些較小的例項求解(一般用遞迴方法,但在問題規模足夠小的時候。有時也會利用另乙個演算法);(3)如果必要的話,合併這些較小問題的解,以得到原始問題的解。

對於乙個需要排序的陣列$a[0...n-1],歸併排序把它一分為二:$a[0..n/2-1]和$a[n/2...n-1],並對每個子陣列遞迴排序,然後把這兩個排好序的子陣列合併為乙個有序陣列。

下面的這個圖能夠很好地解釋歸併排序的整個流程(自己畫的,有點醜)。

看上面的圖,我們就知道了。遞迴的將乙個陣列分成兩部分,直到小的足以解決問題就不再遞迴(乙個數,一定是有序的)。然後再將兩個有序的陣列合併,最後整個陣列就是有序的了。

演算法如下:

1

<?php2 /*

*3* 歸併排序

4* 遞迴呼叫mergesort來對陣列$a排序

5* @param $a 乙個可排序的陣列

6* @return $a 非降序排列的陣列7*/

8function mergesort(&$a)13

$b = array_slice($a, 0, intval($t/2));

14$c = array_slice($a, intval($t/2));

1516

/*echo '

$b: ';

17print_r($b);

18echo '

$c: ';

19print_r($c);

*/20

21 mergesort($b

);22 mergesort($c

);23 merge($b, $c, $a

);24

25/*

echo "

".'$a: ';

26print_r($a);

27echo "

"; */28}

29/**30

* 將兩個有序陣列$y, $z合併為乙個有序陣列$x

31* @param $y, $z, $x

32* @return $x

33*/

34function merge(&$y, &$z, &$x

)else

46$k++;47}

48if($i==$p

)54 }else60}

61}62 ?>

如果想看中間的輸出結果,只需要把mergesort()中的注釋去掉就可以了。

歸併排序與快排相比,歸併排序是規定的排序,這對要排序資料報含多個資訊而要按其中的某乙個資訊排序,要求其他資訊盡量按輸入的順序排列很重要,這也是它比快排有優勢的地方。

排序演算法之歸併排序

歸併排序也是經典的使用分治法思想的代表演算法之一。歸併排序的效率很高,而且是一種穩定的排序。其總體的思想思路就是將待排序的元素分成大致相同的兩個子集合,分別對兩個子集合進行排序,最終將排序的子集合合併成排好序的總集合 歸併排序c 實現如下 include void mergesort int arr...

排序演算法之歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用,歸併排序將兩個已排序的表合併成乙個表。歸併排序基本原理 通過對若干個有序結點序列的歸併來實現排序。所謂歸併是指將若干個已排好序的部分合併成乙個有序的部分。歸併排序基本思...

排序演算法之歸併排序

歸併排序,和快排一樣同樣採用了分治的思想,將兩個 或以上 有序表合併成乙個新的有序表。歸併排序步驟如下 把n個記錄看成 n個長度為 1 的有序子表 進行兩兩歸併使記錄關鍵字有序,得到 n 2 個長度為 2 的有序子表 重複第2步直到所有記錄歸併成乙個長度為n的有序表為止。下面是歸併排序演算法的遞迴實...