3.海量資料的排序問題
歸併排序(merge-sort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。
歸併排序適合於外部排序,也可以適用於鍊錶排序。
外部排序:指的是資料儲存在磁碟上。
鍊錶排序:希爾、堆排序、快速排序等均不適用於鍊錶排序(鍊錶不支援隨機訪問)。
原理:將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。
注意:區間只有乙個元素時,這個區間一定是有序區間。
public
static
void
mergesort
(int
array)
// [low, high)
private
static
void
mergesortinter
(int
a,int low,
int high)
int mid =
(low + high)/2
;// [low, mid)
// [mid, high)
mergesortinter
(a, low, mid)
;//分解
mergesortinter
(a, mid, high)
;//分解
merge
(a, low, mid, high)
;//合併
}private
static
void
merge
(int
a,int low,
int mid,
int high)
else
}// 當上面的迴圈結束的時候, 肯定是 i 或者 j 有乙個先到達末尾
// 把剩下的內容都一股腦拷貝到 extea 中
while
(iwhile
(j// 把 extra 中的元素再搬運回原來的陣列
for(
int x =
0; x
)}
效能分析:
時間複雜度:拆分*合併(分解:o(log(n)) 合併:o(n))
空間複雜度:o(n) + o(log(n)) //合併使用額外空間 + 遞迴占用的空間
如果是針對鍊錶歸併排序:空間複雜度o(1)
思路:通過合理的分組方式實現,不需借用棧。
public
static
void
mergesortbyloop
(int
array)
if(end > array.length)
merge
(array, beg, mid, end)
;//合併}}
}
外部排序:排序過程需要在磁碟等外部儲存進行的排序
前提:記憶體只有 1g,需要排序的資料有 100g
因為記憶體中因為無法把所有資料全部放下,所以需要外部排序,而歸併排序是最常用的外部排序
先把檔案切分成 200 份,每個 512 m
分別對 512 m 排序,因為記憶體已經可以放的下,所以任意排序方式都可以
進行 200 路歸併,同時對 200 份有序檔案做歸併過程,最終結果就有序了
排序4 歸併排序
歸併排序 merge sort 完全遵循上述分治法三個步驟 1 分解 將要排序的n個元素的序列分解成兩個具有n 2個元素的子串行 2 解決 使用歸併排序分別遞迴地排序兩個子串行 3 合併 合併兩個已排序的子串行,產生原問題的解。所以說歸併排序一種分治演算法的典型應用。歸併排序過程動態演示 時間複雜度...
4 歸併排序
一 基本思想 對於乙個待排序的序列,遞迴地將前半部分資料和後半部分資料各自歸併排序,得到排序後的兩部分資料,然後合併這兩個部分。歸併演算法採用分而治之的策略 a.將問題分成一些小的問題然後遞迴求解 b.將分的階段解得的各個答案 修補 到一起。可以看到這種結構很像一棵完全二叉樹,故我們可以採用遞迴來實...
4 內部排序 歸併排序
歸併排序 歸併排序和快速排序這兩種演算法都採用了分治的思想,且速度僅次於 快速排序 為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的 數列,其具體思想如下 1 將序列每相鄰兩個數字進行歸併操作 merge 形成 n 2 個序列,排序後每個序列包含兩個元素 2 將上述序列再次歸併操作,形成 ...