归并排序(稳定的排序):
归并排序是一种分治策略的排序算法,其基本思想是将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后合并这两个已经排序好的子数组,最终得到完整的已排序数组。
具体实现过程如下:
- 将待排序数组从中心位置分成两个子数组,分别为左子数组和右子数组。
- 对左子数组和右子数组分别进行递归排序。
- 将排好序的左子数组和右子数组合并成一个有序数组。
- 重复执行步骤3,直到所有子数组都被合并成一个有序数组。
归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。它是一种稳定排序算法,适用于处理大规模数据的排序任务。
下面我们来看一下代码如何实现
首先是对数组划分
void mergesort(int a[],int low,int high)
{
if (low < high)
{
int mid = (low + high) / 2;//从中间划分两个子序列
mergesort(a, low, mid);//对左侧子序列进行递归排序
mergesort(a, mid + 1, high);//对右侧子序列进行递归排序
merge(a, low, mid, high);//归并排序
}
}
再进行归并
void merge(int a[], int low, int mid, int high)
{
int* B = (int*)malloc(sizeof(int) * (high+ 1));//辅助数组B
int i = 0;
int j = 0;
int k = 0;
for (k = low; k <= high; k++)
B[k] = a[k];//将a中所有元素复制到B中
for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++)
{
if (B[i] <= B[j])//比较B中的左右两段中的元素
a[k] = B[i++];//将较小值复制到a中
else
a[k] = B[j++];
}
while (i <= mid)//若第一个表为检测完,一次复制到a中
a[k++] = B[i++];
while (j <= high)//若第二个表为检测完,一次复制到a中
a[k++] = B[j++];
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
void merge(int a[], int low, int mid, int high)
{
int* B = (int*)malloc(sizeof(int) * (high+ 1));//辅助数组B
int i = 0;
int j = 0;
int k = 0;
for (k = low; k <= high; k++)
B[k] = a[k];//将a中所有元素复制到B中
for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++)
{
if (B[i] <= B[j])//比较B中的左右两段中的元素
a[k] = B[i++];//将较小值复制到a中
else
a[k] = B[j++];
}
while (i <= mid)//若第一个表为检测完,一次复制到a中
a[k++] = B[i++];
while (j <= high)//若第二个表为检测完,一次复制到a中
a[k++] = B[j++];
}
void mergesort(int a[],int low,int high)
{
if (low < high)
{
int mid = (low + high) / 2;//从中间划分两个子序列
mergesort(a, low, mid);//对左侧子序列进行递归排序
mergesort(a, mid + 1, high);//对右侧子序列进行递归排序
merge(a, low, mid, high);//归并排序
}
}
int main()
{
int a[] = { 49,38,65,97,76,13,27 };
int sz = sizeof(a) / sizeof(a[0]);
int j = 0;
printf("原始待排序的数组为:");
for(j = 0; j < sz; j++)
printf("%d ", a[j]);
mergesort(a,0,sz-1);
printf("\n归并排序后的数组为:");
for (j = 0; j < sz; j++)
printf("%d ", a[j]);
return 0;
}