排序演算法(2) 歸併排序,快速排序

2021-07-22 09:11:05 字數 2249 閱讀 7350

分治思想

思想:將兩個有序的陣列歸併成乙個有序陣列。

(下面兩種歸併方法用到):

建立乙個適當大小的陣列,然後將兩個有序陣列乙個個有序的放入所建立的陣列中(在此造成了額外的空間儲存問題)。

方法簽名:merge(array,lo,hi),將子陣列a[lo...mid],a[mid+1...hi]歸併,並將結果放入大a[lo...hi].
原地歸併的抽象方法:

private

static

int aux ;

public

static

void

mergesort(int a, int lo, int mid, int hi)

此類排序使用標準的遞迴方式進行
實現如下:

//消除輸入依賴

public

static

void

sort(int arr)

private

static

void

sort(int a, int lo, int hi)

複雜度

時間複雜度:nlogn

空間複雜度:n

對於長度為n的任意陣列,需要1/2nlgn到nlgn次比較。

最多需要訪問陣列6nlgn次。

思想:先歸併微型陣列,然後再歸併得到的子陣列。(翻倍歸併)
實現如下:

public static void sortbu(int arr)

//最後乙個子陣列的大小,只有在陣列大小是size的偶數倍的時候才會等於size(否則它會比size小).

複雜度

時間複雜度:nlogn

空間複雜度:n

對於長度為n的任意陣列,需要比較次數和訪問陣列次數與自頂向下相同。

運用最為廣泛的排序演算法

同樣是分治演算法思想

思想:

根據切分元素,把陣列分為兩部分,左邊小於(大於)切分元素,右邊大於(小於)切分元素。

實現如下:

private

static

void

quicksort(int a, int lo,int hi)

根據切分方法,可以將快速排序分為兩類:

常規的切分 and 三向切分

private

static

intpartition(int a,int lo, int hi)

exch(a,lo,j);

return j;

}

複雜度:

時間複雜度:nlgn

空間複雜度:lgn

對於長度為n的無重複陣列排序,平均需要~2nlnn次比較,一級1/6的交換。

最多需要n^2次比較,但那時可以用隨機打亂陣列來防止這種最壞情況。

常規切分的改進

對於存在大量相同資料的排序尤為有效快速

實現:

private static void quick3waysort(int a, int lo, int hi)

quick3waysort(a, lo, lt-1);

quick3waysort(a, gt+1, hi);

}

複雜度:

時間複雜度:n~nlogn

空間複雜度:lgn

對於大小為n的陣列,需要~(2ln2)nh次比較。h為由主鍵值出現頻率定義的夏農資訊量。

它是對於包含大量重複資料的最優排序演算法。

歸併演算法和快速演算法比較

快速排序特點:原地排序,只需要乙個很小的輔助棧,空間複雜度僅為lgn。

但是相對於歸併排序此類的穩定排序,要更注意避免低劣效能的產生,經常會導致在實際運用中效能只有平方級別。

參照演算法第四版

排序演算法(2) 歸併排序 快速排序

穩定原地排序 時間複雜度 空間複雜度 歸併排序 o n logn o n 快速排序 o n logn 歸併排序的合併函式,在合併兩個有序陣列為乙個有序的時,需要借助額外的儲存空間 public class mergesort private static void mergesortinternal...

排序演算法 2 歸併排序

歸併排序使用了分治的思想,即將乙個陣列的排序分解為兩個子陣列 首先分解為規模更小的子問題 然後對這兩個子陣列分別排序 分而治之 最後對兩個已排序的子陣列進行合併 合併子問題結果 關鍵在於,合併操作只需要o n 的時間複雜度,那麼根據master定理,歸併排序的整體時間複雜度為o lg n 從漸進時間...

白話排序演算法(歸併排序,快速排序)

排序演算法已經完成了兩篇了 選擇,插入,冒泡 希爾排序 繼續把常用的演算法完成掉,下面我們來討論下關於歸併排序,快速排序,這兩種高階排序演算法。這兩種演算法是線性的也即對於o nlogn 的排序演算法。歸併排序 歸併排序用的是分治 divide and conquer 的思想 分治也是乙個很不錯的演...