外部排序 歸併演算法實現

2021-08-11 15:35:23 字數 3488 閱讀 1776

基本要點:外部排序顧名思義是對外部儲存空間中資料的排序,那為什麼不能像選擇排序、插入排序、快速排序那樣也直接進行排序呢?原因是外部儲存的資料量可能是非常大的,而計算機的記憶體大小要遠遠小於外存,計算機一下子讀不了那麼多資料,無法一次性對它們進行排序,這就是外部排序產生的原因。

基本思想

我們這裡借助歸併排序的思想(這也是外部排序中最基本的思想,假設大家已經對歸併排序有一定了解),假設我的乙個檔案中有10000個資料,而我的記憶體每次只能讀2000個資料,那我先對檔案預處理一下,將原檔案切割成5個小檔案,每個檔案中有2000個有序資料(在讀入記憶體2000個資料後,對資料排序後再寫入到新檔案中)。

然後我們開始進行檔案合併(這裡採用2-路歸併)。先分別開啟兩個檔案,分別讀取檔案的第一行資料,把資料較小的寫入到乙個新檔案中,然後把資料較小的檔案再往下讀一行,直到兩個檔案中的資料全部有序地寫到新檔案中為止,這樣原先5個2000個資料的檔案變為2個4000個資料和1個2000個資料的檔案。

重複步驟2,再次合併變為1個8000個資料和1個2000個資料的檔案,再次合併變為1個10000個資料的檔案。排序完成,原先有10000個資料的檔案變得有序。

下面是模擬外部排序的**:

#include

#include

#include

#include

#define maxnum 2000

int filenum;

int filenumtemp;

int filenumend;

void creatfile()

fclose(f);

}void merge(int num, int start, int mid, int end)

void merge_sort(int num, int start, int end)

}void mergefile()

; filenumtemp++;

filename1[0] = filenumtemp + 48;

strcat(filename1, ".txt");

f1 = fopen(filename1, "r");

filenumend++;

char filename[10] = ;

filename[0] = filenumend + 48;

strcat(filename, "temp.txt");

f = fopen(filename, "w+");

int num1;

while (fscanf(f1, "%d", &num1) != eof)

fclose(f1);

fclose(f);

}else

;filenumtemp++;

filename1[0] = filenumtemp + 48;

strcat(filename1, ".txt");

f1 = fopen(filename1, "r");

char filename2[10] = ;

filenumtemp++;

filename2[0] = filenumtemp + 48;

strcat(filename2, ".txt");

f2 = fopen(filename2, "r");

filenumend++;

char filename[10] = ;

filename[0] = filenumend + 48;

strcat(filename, "temp.txt");

f = fopen(filename, "w+");

int temp;

int count = 0;

int num1, num2;

fscanf(f1, "%d", &num1);

fscanf(f2, "%d", &num2);

while (true)

break;}}

else

break;}}

}fclose(f1);

fclose(f2);

fclose(f);

}char filename1[10] = ;

char filename2[10] = ;

filename1[0] = filenumend + 48;

filename2[0] = filenumend + 48;

strcat(filename1, "temp.txt");

strcat(filename2, ".txt");

char filename3[10] = ;

char filename4[10] = ;

filename3[0] = filenumend * 2 - 1 + 48;

filename4[0] = filenumend * 2 + 48;

strcat(filename3, ".txt");

strcat(filename4, ".txt");

int r1 = remove(filename3);

int r2 = remove(filename4);

printf("r1=%d r2=%d\n", r1, r2);

rename(filename1, filename2);

//printf("filenum=%d filenumtemp=%d filenumend=%d\n", filenum, filenumtemp, filenumend);

if (filenumtemp == filenum&&filenum != 1)}}

char filename1[20] = ;

char filename2[20] = ;

filename1[0] = 1 + 48;

strcat(filename1, ".txt");

strcat(filename2, "test_sort.txt");

rename(filename1, filename2);

printf("排序完成,有序序列儲存在:test_sort.txt檔案中\n");

}void creattempfile(int temp, int count)

; filename[0] = filenum + 48;

strcat(filename, ".txt");

f = fopen(filename, "w+");

for (int i = 0; i < count; ++i)

fclose(f);

}void sortfile()

}if (count != 0)

fclose(f);

free(temp);

}int main()

:使用敗者樹進行多路合併可加快檔案的排序速度,這裡只使用了2-路歸併排序,對原檔案的預處理排序可使用內部排序的任何一種演算法,當然效率越快,排序穩定最好。

外部排序 歸併排序

歸併排序 歸併排序是採用分治的思想,將陣列劃分為兩個子陣列,然後遞迴的將每個子陣列再進行劃分,直到陣列中只剩一下乙個元素,然後開始排序合併,直到將所有的子陣列合併完成,整個資料就是有序的了。歸併排序乙個重要的操作函式就是合併函式 時間複雜度 將陣列分成的子陣列 用二叉樹表示,假設共有n層,第k層共有...

歸併排序 外部排序

基本思想 先對資料進行均分 左右兩半部分 均分到左右部分已經有序 歸併 歸併排序核心步驟 分組 歸併 外部排序 void mergesortnor int array,int size void print int array,int size endif mergesort h mergesort...

歸併排序演算法實現

const int maxn 100 將陣列a的 l1,r1 與 l2,r2 區間合併為有序區間 此處l2即為r1 1 void merge int a,int l1,int r1,int l2,int r2 while i r1 temp index a i 將 l1,r1 剩餘元素加入temp ...