归并排序算法
归并排序(Merge Sort)是一种基于分治思想的排序算法,它的核心思想是将原始数组拆分成较小的子数组,然后递归地排序这些子数组,最后将排好序的子数组合并成一个整体有序的数组。
归并排序的基本步骤如下:
拆分阶段: 将原始数组递归地拆分为较小的子数组,直到每个子数组只包含一个元素。
合并阶段: 将两个有序子数组合并为一个有序数组。
递归合并: 递归地将子数组两两合并,直到所有元素都被合并成一个完整的有序数组。
归并排序的核心操作是合并操作。在合并操作中,需要比较两个有序子数组的元素,并按顺序将它们合并成一个更大的有序数组。通过不断递归地将数组拆分并合并,最终得到整个数组的有序排列。
具体代码如下
#include <stdio.h>
#include <stdlib.h>
// 合并两个子数组为一个有序数组
void merge(int arr[], int left, int mid, int right) {
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;
// 创建临时数组存储两个子数组的内容
int* L = (int*)malloc(n1 * sizeof(int));
int* R = (int*)malloc(n2 * sizeof(int));
//将数组复制到临时数组中
for(i=0;i<n1;i++)
L[i]=arr[left+i];
for(j=0;j<n2;j++)
R[j]=arr[mid+1+j];
//合并两个临时数组为一个有序数组
i=0;
j=0;
k=left;
while(i<n1&&j<n2){
if(L[i]<=R[j]){
arr[k]=L[i];
i++;
}
else{
arr[k]=R[j];
j++;
}
k++;
}
//将剩余元素复制回原数组
while(i<n1){
arr[k]=L[i];
i++;
j++;
}
while (j<n2){
arr[k]=R[j];
j++;
k++;
}
//释放临时数组的内存
free(L);
free(R);
}
//归并排序函数
void mergeSort(int arr[],int left,int right){
if(left<right){
int mid=left+(right-left)/2;
//递归排序左右两个部分
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
//合并两个已排序的子数组
merge(arr,left,mid,right);
}
}
//测试归并算法
int main(){
int arr[]={12,8,59,24,6556,47,2,3,58,3699,44};
int n=sizeof(arr)/sizeof(arr[0]);
printf("原始数组为:");
for(int i=0;i<n;i++){
printf("%d ",arr[i]);
}
printf("\n");
mergeSort(arr,0,n-1);
printf("排序后的数组为:");
for(int i=0;i<n;i++){
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
归并排序的时间复杂度是 O(n log n),其中 n 是数组的长度。这使得归并排序在各种情况下都具有稳定且较高效的性能,尤其对于大型数据集。但是,它需要额外的内存空间用于存储临时数组,在空间复杂度方面可能略高于其他原地排序算法。