/*exp11-7.cpp*/
#include <stdio.h>
#include <malloc.h>
#define MAXE 20/*線性表中最多元素個數*/
typedef int KeyType;
typedef char InfoType[10];
typedef struct/*記錄類型*/
{
KeyType key;/*關鍵字項*/
InfoType data;/*其他資料項目,類型為InfoType*/
}RecType;
void Merge(RecType R[],int low,int mid,int high)/*將兩個有序表R[low...mid]和R[mid+1...high]歸併為一個有序表R[low...high]*/
{
RecType *R1;
int i=low,j=mid+1,k=0;/*k是R1的下標,i,j分別為第1,2段的下標*/
R1=(RecType *)malloc((high-low+1)*sizeof(RecType));/*動態分配*/
while(i<=mid && j<=high)/*在第1段中的記錄放入R1中*/
if(R[i].key<=R[j].key)/*將第1段中的記錄放入R1中*/
{
R1[k]=R[i];
i++;k++;
}
else/*將第2段中記錄放入R1中*/
{
R1[k]=R[j];
j++;k++;
}
while(i<=mid)/*將第1段餘下部分複製到R1*/
{
R1[k]=R[i];
i++;j++;
}
while(j<=high)/*將第2段餘下部分複製到R1*/
{
R1[k]=R[j];
j++;k++;
}
for(k=0,i=low;i<=high;k++,i++)/*將R1複製回R中*/
R[i]=R1[k];
}
void MergePass(RecType R[],int length,int n)/*實現一趟歸併*/
{
int i;
for(i=0;i+2*length-1<n;i=i+2*length)/*歸併length長的兩相鄰子表*/
Merge(R,i,i+length-1,i+2*length-1);
if(i+length-1<n)/*餘下兩個子表,後者長度小於length*/
Merge(R,i,i+length-1,n-1);/*歸併這兩個子表*/
}
void MergeSort(RecType R[],int n)/*二路歸併排序演算法*/
{
int length,k,i=1;/*i用於累計歸併的趟數*/
for(length=1;length<n;length=2*length)
{
MergePass(R,length,n);
printf(" 第%d趟歸併 ",i++);/*輸出每一趟的排序結果*/
for(k=0;k<n;k++)
printf("%4d",R[k].key);
printf("\n");
}
}
void main()
{
int i,k,n=8;
KeyType a[]={18,2,20,34,12,32,6,16};
RecType R[MAXE];
for(i=0;i<n;i++)
R[i].key=a[i];
printf("\n");
printf(" 初始關鍵字 ");
for(k=0;k<n;k++)/*輸出初始關鍵字序列*/
printf("%4d",R[k].key);
printf("\n");
MergeSort(R,n);
printf(" 最後結果 ");
for(k=0;k<n;k++)/*輸出最後關鍵字序列*/
printf("%4d",R[k].key);
printf("\n\n");
}