归并排序是建立在归并操作操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完整有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
算法描述:
- 把长度为n的输入序列分为两个长度为n/2的子序列
- 对这两个子序列分别采用归并排序
- 将两个排序好的子序列合并成一个最终的排序序列
代码实现:
# include<stdio.h>
# include<stdlib.h>
# include<assert.h>
void Meger(int *arr, int len, int width)
{
int low1 = 0;
int high1 = low1 + width - 1;
int low2 = high1 + 1;
int high2 = low2 + width - 1 < len - 1 ? low2 + width - 1 : len - 1;
int *brr = (int *)malloc(sizeof(int)* len);
assert(brr != NULL);
int index = 0;
while (low1 < len)//只要有一个段还没合并进brr中,循环都得执行
{
//按顺序归并两个相邻的段,退出时,有可能第一个段数据归并完成,也有可能第二个段数据归并完成
while (low1 <= high1 && low2 <= high2)
{
if (arr[low1] < arr[low2])
{
brr[index++] = arr[low1++];
}
else
{
brr[index++] = arr[low2++];
}
}
while (low1 <= high1)
{
brr[index++] = arr[low1++];
}
while (low2 <= high2)
{
brr[index++] = arr[low2++];
}
low1 = high2 + 1;
high1 = low1 + width - 1 < len - 1 ? low1 + width - 1 : len - 1;
low2 = high1 + 1;
high2 = low2 + width - 1 < len - 1 ? low2 + width - 1 : len - 1;
}
for (int i = 0; i < len; ++i)
{
arr[i] = brr[i];
}
free(brr);
}
void MegerSort(int *arr, int len)
{
for (int i = 1; i < len; i *= 2)
{
Meger(arr, len, i);
}
}
void Show(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 2, 7, 96, 45, 32, 45, 76, 29, 94 };
int len = sizeof(arr) / sizeof(arr[0]);
Show(arr, len);
MegerSort(arr, len);
Show(arr, len);
return 0;
}
算法特性:
时间复杂度 | 空间复杂度 | 稳定性 |
O(nlogn) | O(n) | 稳定 |