兩路歸并算法
歸并排序(Merge Sort)是利用"歸并"技術來進行排序。歸并是指將若干個已排序的子文件合并成一個有序的文件。
兩路歸并算法
1、算法基本思路
設兩個有序的子文件(相當于輸入堆)放在同一向量中相鄰的位置上:R[low..m],R[m+1..high],先將它們合并到一個局部的暫存向量R1(相當于輸出堆)中,待合并完成后將R1復制回R[low..high]中。
(1)合并過程
合并過程中,設置i,j和p三個指針,其初值分別指向這三個記錄區的起始位置。合并時依次比較R[i]和R[j]的關鍵字,取關鍵字較小的記錄復制到R1[p]中,然后將被復制記錄的指針i或j加1,以及指向復制位置的指針p加1。
重復這一過程直至兩個輸入的子文件有一個已全部復制完畢(不妨稱其為空),此時將另一非空的子文件中剩余記錄依次復制到R1中即可。
(2)動態申請R1
實現時,R1是動態申請的,因為申請的空間可能很大,故須加入申請空間是否成功的處理。
2、歸并算法
void Merge(SeqList R,int low,int m,int high)
{//將兩個有序的子文件R[low..m)和R[m+1..high]歸并成一個有序的
//子文件R[low..high]
int i=low,j=m+1,p=0; //置初始值
RecType *R1; //R1是局部向量,若p定義為此類型指針速度更快
R1=(ReeType *)malloc((high-low+1)*sizeof(RecType));
if(! R1) //申請空間失敗
Error("Insufficient memory available!");
while(i<=m&&j<=high) //兩子文件非空時取其小者輸出到R1[p]上
R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++];
while(i<=m) //若第1個子文件非空,則復制剩余記錄到R1中
R1[p++]=R[i++];
while(j<=high) //若第2個子文件非空,則復制剩余記錄到R1中
R1[p++]=R[j++];
for(p=0,i=low;i<=high;p++,i++)
R[i]=R1[p];//歸并完成后將結果復制回R[low..high]
} //Merge

浙公網安備 33010602011771號