問: 目前給你乙個包含20億個int型別的整數,計算機的記憶體只有2gb,該怎麼排序?乙個int數占4個位元組(byte), 20億個int型別佔
20*4=80
億個位元組, 80億個位元組大概要占用8gb的記憶體,而計算機只有2gb的記憶體
計算機裝不下。為了解決這個問題,我們可以將8gb的資料平分成4個2gb的資料來排,排好之後再把它們拼湊回去。
排序的時候我們可以選擇快速排序或歸併排序等演算法。
接著我們可以把兩個小的有序子串合併成乙個大的有序子串。
注意:讀取的時候是每次讀取乙個int數,通過比較之後在輸出。
按照這個方法來回合併,總共經過三次合併之後就可以得到8g的有序子串。
問: 舉個例子我們先假設需要排序的int數有12個,記憶體一次只能裝下3個int數
接下來把12個資料分成4份,然後排序成有序子串
然後把子串進行兩兩合併 【兩路歸併】
輸出哪個元素,就在那個元素所在的有序子串再次讀入乙個元素
繼續
重複直到合併成乙個包含6個int的有序子串
再把兩個包含6個int的有序子串合併成乙個包含12個int資料的最終有序子串
問: 剛剛的那個例子有很大的問題,請問是什麼?io消耗太大,每個資料都從硬碟讀了3次,寫了3次。而硬碟的讀寫速度比記憶體慢得多,花了太多時間在硬碟的讀寫上。
問:該怎麼優化呢?第一反應就是減少硬碟讀寫的次數。
剛剛在歸併的時候,我們採用的是兩路歸併,就是每次從磁碟讀寫兩個資料。如果想要減少硬碟io讀寫次數,我們可以每次從硬碟中讀出來的就是多一點就可以了啊,也就是多路歸併
比如:假設記憶體一共可以裝4個int型資料。我們每次讀取4個資料(四路歸併)歸併成有序子串,這樣就只需要讀寫3次io就可以了
如果每次讀取n個歸併成有序子串,這樣的演算法叫做n路歸併
問: n是越大越好嗎?不是, n越大,io次數越少(將n個資料讀取到記憶體中);但是由於在合併的時候,需要從n個資料中選出乙個最小值,而n約到,選取就越花時間。
問:還可以繼續優化嗎?我們採用另外一種排序方法
假設當前硬碟有12個無序的int型別的資料
讀入3個到記憶體中
構建最小堆,且選出目標數
讀入下乙個數86
讀入下乙個數3,比70小,暫放一邊,不加入堆結構中
讀入下乙個資料24,比81小,不加入堆結構
讀入下乙個資料8,比86小,不加入堆結構。此時p1已經完成了,把那些剛才暫放一邊的數重新構成乙個堆,繼續p2的存放。
以此類推…
最後生成的p2如下:
這樣下來,最後只生成了2個有序子串,我們把這種方法稱之為置換選擇
按照這種方法的話:
這種方法適合要排序的資料太多,以至於記憶體一次性裝載不下。只能通過把資料分幾次的方式來排序,我們也把這種方法稱之為外部排序
總結:
從12個資料中讀取3個資料,構建成乙個最小堆,然後從堆頂選擇乙個數寫入到p1中。
之後再從剩餘的9個數中讀取乙個數,如果這個數比剛才那個寫入到p1中的數大,則把這個數插入到最小堆中,重新調整最小堆結構,然後在堆頂選乙個數寫入到p1中。
否則,把這個數暫放在一邊,暫時不處理。之後一樣需要調整堆結構,從堆頂選擇乙個數寫入到p1中。
這裡說明一下,那個被放在一邊的數是不能再放入p1中的了,因為它一定比p1中的數都要小,所以它會放在下乙個子串中
漫畫 什麼是 「混合雲」?
什麼是私有雲呢?所謂私有雲,是雲服務商為乙個客戶單獨使用而構建的雲。私有雲提供了對資料 安全性和服務質量的最有效控制。私有雲既可以部署在企業資料中心的防火牆內,也可以將它們部署在乙個安全的主機託管場所。打個比方,私有雲就像是每一家都住在自建房裡,空間完全是自己私有的,不會被其他住戶所打擾。私有雲雖然...
漫畫 什麼是拜占庭將軍問題
接觸區塊鏈的同學,多少都聽說過拜占庭將軍問題,經常看到或聽到某某區塊鏈使用某某演算法解決了拜占庭將軍問題,那麼究竟什麼是拜占庭將軍問題呢?也被稱為 拜占庭容錯 拜占庭將軍問題 拜占庭將軍問題是leslie lamport 2013年的圖靈講得主 用來為描述分布式系統一致性問題 distributed...
漫畫 什麼是紅黑樹?
系列文章 漫畫 什麼是一致性雜湊?漫畫 什麼是b 樹?漫畫 什麼是b 樹?漫畫 什麼是跳躍表?漫畫 什麼是動態規劃?漫畫 當程式猿遇上智力測試題 漫畫 判斷 2 的乘方 漫畫演算法 最小棧的實現 漫畫 什麼是大資料?漫畫演算法 無序陣列排序後的最大相鄰差值 漫畫 什麼是bitmap演算法?漫畫 bi...