分治思想
思想:將兩個有序的陣列歸併成乙個有序陣列。
(下面兩種歸併方法用到):
建立乙個適當大小的陣列,然後將兩個有序陣列乙個個有序的放入所建立的陣列中(在此造成了額外的空間儲存問題)。
方法簽名: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 的思想 分治也是乙個很不錯的演...