C語言之合併排序
阿新 • • 發佈:2019-01-03
一、基本運算:
兩路合併排序:將兩個有序序列合併成一個有序序列。
二、步驟:
①把待排序的序列分成長度為1的子序列(只包含一個記錄的序列被認為是有序的)→得到n個長度為1的有序子序列;
②實施兩兩合併,合併相鄰的兩個子序列→得到大約n/2個長度為2的有序子序列;
③重複步驟②,直到合併成一個長度為n的有序序列為止。
三、注意:
當待排序序列個數為奇數時,最後一個長度為1的子序列則在最後一趟進行排序。
四、舉例:
以對序列A[0], A[l]…, A[n-1]進行升序排列來進行講解,在此採用自頂向下的實現方法,操作步驟如下。
①將所要進行的排序序列分為左右兩個部分,如果要進行排序的序列的起始元素下標為first,最後一個元素的下標為last,那麼左右兩部分之間的臨界點下標mid=(first+last)/2,這兩部分分別是A[first … mid]和A[mid+1 … last];
②將上面所分得的兩部分序列繼續按照步驟(1)繼續進行劃分,直到劃分的區間長度為1;
③將劃分結束後的序列進行歸併排序,排序方法為對所分的n個子序列進行兩兩合併,得到n/2或n/2+l個含有兩個元素的子序列,再對得到的子序列進行合併,直至得到一個長度為n的有序序列為止。
五、函式:
Merge函式
①功能:將兩個有序序列合併成一個有序序列;
②C程式碼:
void Merge(int arr[],int low,int mid,int high) { int left_low=low; //左邊序列的左下標 int left_high=mid; int right_low=mid+1; //右邊序列的左下標 int right_high=high; int tmp[N],k=0,i; //陣列tmp用來存放序列元素 while(left_low<=left_high&&right_low<=right_high) //當左右序列都有元素時執行迴圈 { if(arr[left_low]<arr[right_low]) tmp[k++]=arr[left_low++]; //元素小的放進陣列tmp else tmp[k++]=arr[right_low++]; } if(left_low<=left_high){ //左邊序列還有元素時 for(i=left_low;i<=left_high;i++) tmp[k++]=arr[left_low++]; } if(right_low<=right_high){ //右邊序列還有元素時 for(i=right_low;i<=right_high;i++) tmp[k++]=arr[right_low++]; } for(i=0;i<high-low+1;i++){ //將陣列tmp中的元素賦給陣列arr,從而陣列arr有序 arr[low+i]=tmp[i]; } }
MergeSort函式
①功能:通過呼叫自身分裂子序列;通過呼叫Merge函式實現兩路合併排序。
②程式碼:
void MergeSort(int arr[],int first,int last) { int mid = 0; if(first<last){ mid = (first+last)/2; /* 注意防止溢位 */ MergeSort(arr, first, mid); MergeSort(arr, mid+1,last); Merge(arr,first,mid,last); } }
六、程式碼
#include <stdio.h>
#include <stdlib.h>
#define N 7
void Merge(int arr[],int low,int mid,int high)
{
int left_low=low; //左邊序列的左下標
int left_high=mid;
int right_low=mid+1; //右邊序列的左下標
int right_high=high;
int tmp[N],k=0,i; //陣列tmp用來存放序列元素
while(left_low<=left_high&&right_low<=right_high) //當左右序列都有元素時執行迴圈
{
if(arr[left_low]<arr[right_low])
tmp[k++]=arr[left_low++]; //元素小的放進陣列tmp
else
tmp[k++]=arr[right_low++];
}
if(left_low<=left_high){ //左邊序列還有元素時
for(i=left_low;i<=left_high;i++)
tmp[k++]=arr[left_low++];
}
if(right_low<=right_high){ //右邊序列還有元素時
for(i=right_low;i<=right_high;i++)
tmp[k++]=arr[right_low++];
}
for(i=0;i<high-low+1;i++){ //將陣列tmp中的元素賦給陣列arr,從而陣列arr有序
arr[low+i]=tmp[i];
}
}
void MergeSort(int arr[],int first,int last)
{
int mid = 0;
if(first<last){
mid = (first+last)/2; /* 注意防止溢位 */
MergeSort(arr, first, mid);
MergeSort(arr, mid+1,last);
Merge(arr,first,mid,last);
}
}
int main(){
int i;
int a[N]={32,12,56,78,76,45,36};
printf ("排序前:");
for(i=0;i<N;i++)
printf("%d\t",a[i]);
MergeSort(a,0,N-1); // 排序
printf ("\n排序後:");
for(i=0;i<N;i++)
printf("%d\t",a[i]); printf("\n");
return 0;
}