归并排序
是建立在归并操作的一种高效的排序方法,该方法采用了分治的思想,比较适用于处理较大规模的数据,但比较消耗内存
归并排序的思想:
就是将排序的数分成两半,分别对这两组数据进行排序,然后再将这两个排好序的序列合并成一个有序的数组
合并两个有序的序列:
代码:
#include<stdio.h>
#include<stdlib.h>
void MergeSort(int arr[], int tmp[], int center, int left, int right)
{
int i = left;
int j = center + 1;
int k = 0;//辅助数组的下标
for (k = left; k <= right; k++)
{
//如果左边数组的所有元素都已经比较完
//那就把右边数组没有元素全部都拷贝到辅助数组中,右边数组同理
if (i > center)
tmp[k] = arr[j++];
else if (j > right)
tmp[k] = arr[i++];
else if (arr[i] < arr[j])
tmp[k] = arr[i++];
else
tmp[k] = arr[j++];//此时arr[i]>arr[j]
}
//最后再把排好序的辅助数组中的所有元素复制回原数组
for (k = left; k <= right; k++)
{
arr[k] = tmp[k];
}
}
void Merge(int arr[], int left, int right)
{
int tmp[20] = { 0 };
//left==right的时候,就递归到只有一个元素的时候了---->终止递归的条件
if (left < right)//分的时候,递归到剩下一个元素时,结束递归,开始排序
{
int center = (right - left) / 2 + left;//分为两个有序的序列
Merge(arr, left, center);//将左边的数组排序,(left-->center)
Merge(arr, center + 1, right);//将右边的数组排序(center--->right)
MergeSort(arr, tmp, center, left, right);//合并两个数组
}
}
void Print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 1, 4, 6, 8, 2, 3, 9, 0, 5, 7,
23, 34,12,49,39,44,10,15,19,20 };
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
Print(arr, sz);
Merge(arr,left,right);
Print(arr, sz);
system("pause");
return 0;
}
运行结果:
注意:递归太深的话,会发生栈溢出