一 定義
外部排序指的是大檔案的排序,即待排序的記錄儲存在外儲存器上,待排序的檔案無法一次裝入記憶體,需要在記憶體和外部儲存器之間進行多次資料交換,以達到排序整個檔案的目的。
二 處理過程
(1)按可用記憶體的大小,把外存上含有n個記錄的檔案分成若干個長度為l的子檔案,把這些子檔案依次讀入記憶體,並利用有效的內部排序方法對它們進行排序,再將排序後得到的有序子檔案(又稱歸併段)重新寫入外存;
(2)對這些有序子檔案逐趟歸併,使其逐漸由小到大,直至得到整個有序檔案為止。
先從乙個例子來看外排序中的歸併是如何進行的?
假設有乙個含10000 個記錄的檔案,首先通過10 次內部排序得到10 個初始歸併段r1~r10 ,其中每一段都含1000 個記錄。然後對它們作如圖10.11 所示的兩兩歸併,直至得到乙個有序檔案為止 如下圖
三 敗者樹
歸併的方式最容易想到的是兩路歸併。
將40個檔案編號1-40,1和2歸併,3和4歸併...39和40歸併,生成了20個檔案,再將這20個檔案繼續兩路歸併。
從40個檔案變成20個檔案,相當於把所有10g的資料從磁碟讀出,再寫到磁碟上,從20個檔案到10個檔案,也相當於把10g的資料從磁碟讀出,再寫到磁碟上。這種磁碟io操作一共要執行6次。(2^6=64>40)
再來考慮k路歸併。所謂k路歸併,就是一次比較k路資料,選出最小的。例如當k=10,則是將40個檔案分成1-10,11-20,21-30,31-40。對1-10,由於已序,故只要比較出這10個檔案的第乙個數,看哪個最小,哪個就寫到新檔案,再進行下一輪的比較。這樣,只要2次磁碟io就可以了。
假設我們將檔案分為m份,使用k路歸併,則磁碟io的次數就是log k底m。我們當然是希望這個值越小越好。但是是不是k越大就越好呢?我們來看看演算法的時間複雜度。
對於總共s個資料的k路歸併,每次需比較k-1次,才能得出結果中的乙個資料,s個資料就需要比較(s-1)(k-1)次
對於總共n個資料,分為m份,使用k路歸併,總共需要比較 (log k底m) * (n-1)(k-1)= (logm/logk)*(n-1)(k-1) = logm*(n-1)*(k-1)/logk,當k增大時,(k-1)/logk是增大的,也即時間複雜度是上公升的。因此要麼k不能太大,要麼找出乙個新的方法,使得每次不用比較k-1次才得出結果中的乙個資料。我們選擇後者,由此引出了敗者樹。
敗者樹實際上是一棵完全二叉樹,敗者樹重構過程如下:
比較沿著到根結點的路徑不斷進行,直到ls[1]處。把敗者存放在結點ls[1]中,勝者存放在ls[0]中。
相當於每次ls[0]取的都是當前的最大(最小)值,取完一次後,再讀入新的資料,進行新一輪的重構,直到資料讀完。
排序之外部排序
有時,待排序的檔案很大,計算機記憶體不能容納整個檔案,這時候對檔案就不能使用內部排序了 這裡做一下說明,其實所有的排序都是在記憶體中做的,這裡說的內部排序是指待排序的內容在記憶體中就可以完成,而外部排序是指待排序的內容不能在記憶體中一下子完成,它需要做內外存的內容交換 外部排序常採用的排序方法也是歸...
排序之外部排序
有時,待排序的檔案很大,計算機記憶體不能容納整個檔案,這時候對檔案就不能使用內部排序了 這裡做一下說明,其實所有的排序都是在記憶體中做的,這裡說的內部排序是指待排序的內容在記憶體中就可以完成,而外部排序是指待排序的內容不能在記憶體中一下子完成,它需要做內外存的內容交換 外部排序常採用的排序方法也是歸...
外部排序 歸併排序
歸併排序 歸併排序是採用分治的思想,將陣列劃分為兩個子陣列,然後遞迴的將每個子陣列再進行劃分,直到陣列中只剩一下乙個元素,然後開始排序合併,直到將所有的子陣列合併完成,整個資料就是有序的了。歸併排序乙個重要的操作函式就是合併函式 時間複雜度 將陣列分成的子陣列 用二叉樹表示,假設共有n層,第k層共有...