多路歸併排序

2021-06-22 22:30:12 字數 1923 閱讀 1107

下面的問題描述及相關文字都參考於csdn中july的部落格,在此對july表示感謝。july的部落格位址如下:

在對海量資料排序時,有時不能把資料全部匯入到記憶體中,這時需要用到多路歸併排序。

比如輸入:乙個最多含有n個不重複的正整數(也就是說可能含有少於n個不重複正整數)的檔案,其中每個數都

小於等於

n,且n=10^7。

輸出:得到按從小到大公升序排列的包含所有輸入的整數的列表。

條件:最多有大約1mb的記憶體空間可用,但磁碟空間足夠。且要求執行時間在5分鐘以下,10秒為最佳結果。

解答:1、記憶體排序

由於要求的可用記憶體為 1mb,那麼每次可以在記憶體中對 250k 的資料進行排序,然後將有序的數寫入硬碟。那麼 10m 的資料需要迴圈 40 次,最終產生 40 個有序的檔案。

2、歸併排序

1. 將每個檔案最開始的數讀入(由於有序,所以為該檔案最小數),存放在乙個大小為40 的 first_data 陣列中;

2. 選擇 first_data 陣列中最小的數 min_data,及其對應的檔案索引 index;

3. 將 first_data 陣列中最小的數寫入檔案 result,然後更新陣列 first_data(根據 index讀取該檔案下乙個數代替 min_data);

4. 判斷是否所有資料都讀取完畢,否則返回 2。

流程圖如下:

自己寫的對19個陣列進行5路歸併的程式,只是簡單實現。

假定5個陣列已經分別排好序了:,,,, 0

511184

79146

8121710

1315161

23剛開始時,從5個陣列中讀入最初的資料到tmp[5]陣列中,即0,4,6,10,1.找出最小的值為0,在第0個陣列中。把0放入最終的接收陣列data中,並把第0個陣列更新,data[0]=0:05

111847

91468

1217

1013

151612

3 此時最小值為1,在第4個陣列中,data[1]=1:05

111847

91468

1217

1013

151612

3 data[2]=205

111847

91468

1217

1013

151612

3 ...

直至全部比較完。

#include #include #include #include #include using namespace std;

const int max=9999;

int main()

;//接收最終的有序陣列

//等待歸併的5個有序子陣列

int a0[4]=;

int a1[4]=;

int a2[4]=;

int a3[4]=;

int a4[3]=;

int len0,len1,len2,len3,len4;

len0=len1=len2=len3=4;

len4=3;

int i[5]=;//指標陣列,i[0]指向第乙個陣列,i[1]指向第二個陣列.....

int k=0;

int tmp[5]=;

while(i[0]tmp[j])

}i[pos]++;//指標往後移動乙個

data[k++]=min;//記錄

} for(int i=0;i

多路歸併排序

我們有如下乙個問題 對於若干個長度相同的序列,將其合併成乙個有序的序列。暴力的方法顯然是不可取的,這裡可以利用優先佇列來處理這個問題。首先從簡單的開始,對於2路歸併排序,設兩個序列為,將,排序,有 a1 a2 a3 an b1 b2 b3 bn 建立乙個優先佇列,佇列中首先存入元素 a1,0 b1,...

多路歸併排序

雪壓枝頭低,雖低不著泥 今天準備放假,無聊看到乙個場景題,問題如下 有乙個檔案裡面儲存著很多很多很多的無序的數,然後要求進行乙個排序,記憶體限定,磁碟足夠 然後搗鼓了一下,學到了一種新技能 多路歸併排序 學習的過程是這樣的 第一步 把儲存著很多很多很多數的檔案進行切割,切割成n個小檔案,每個小檔案都...

多路歸併排序的實現

為了更好地測試程式,首先利用以下方法生成了1000000個整數,每個整數均不相同 生成隨機排列的1000000個數字,每個數字都不相同 const int size 1000000 int num size void produce srand unsigned time null 隨機交換隨機的兩...