归并排序:
思想:利用将两个的有序数据序列合并成一个新的有序数据序列,在如何分成两个有序数据的问题下,采用分治算法。
时间复杂度:O(n*logn)
空间复杂度:O(n)
是否稳定: 稳定
代码实现如下:
1。递归式
#include
#include
#include
#include
#pragma warning (disable:4996)
void MergeData(int* arr, int left, int mid, int right, int* tmp)
{
int begin1 = left;
int end1 = mid;
int begin2 = mid;
int end2 = right;
int count = left;
while ((begin1 < end1) && (begin2 < end2))// 两个有序数组的合并
{
if (arr[begin1] <= arr[begin2])
{
tmp[count++] = arr[begin1++];
}
else{
tmp[count++] = arr[begin2++];
}
}
while (begin1 < end1) { //第二个数组已全部注入到排序数组中,第一数组有剩余元素
tmp[count++] = arr[begin1++];
}
while (begin2 < end2) { //第二个数组未排完
tmp[count++] = arr[begin2++];
}
}
//区间为左闭右开 [)
void MergeSort(int* arr, int left, int right, int* tmp)//分治算法
{
if (right - left > 1)//递归出口
{
int mid = left + ((right - left) >> 1);
MergeSort(arr, left, mid, tmp);
MergeSort(arr, mid , right, tmp);
MergeData(arr, left, mid, right, tmp);//数据排序
memcpy(arr + left , tmp + left, sizeof(arr[0]) * (right - left));//拷贝排序已好的数据
}
}
void Sort(int* arr, int size) //开辟一个辅助空间
{
int* tmp = (int*)malloc(sizeof(arr[0])*size);//申请空间
if (NULL == tmp) //检验空间是否申请成功
return;
MergeSort(arr, 0, size, tmp);
free(tmp);//堆上空间用完要释放,否则导致内存泄露
}
void printf_arr(int arr[],int size) //打印数组
{
int i = 0;
for (; i < size; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
//int arr[10] = {2,7,1,4,3,9,6,0,5,8};
int arr[10] = { 4,4,6,7,3,0,9,3,5,2 };
int size = sizeof(arr) / sizeof(arr[0]);
Sort(arr, size);
printf_arr(arr, size);
system("pause");
return 0;
}
2。循环式
#include
#include
#include
#include
#pragma warning (disable:4996)
void MergeData(int* arr, int left, int mid, int right, int* tmp)
{
int begin1 = left;
int end1 = mid;
int begin2 = mid;
int end2 = right;
int count = left;
while ((begin1 < end1) && (begin2 < end2))
{
if (arr[begin1] <= arr[begin2])
{
tmp[count++] = arr[begin1++];
}
else{
tmp[count++] = arr[begin2++];
}
}
while (begin1 < end1) {
tmp[count++] = arr[begin1++];
}
while (begin2 < end2) {
tmp[count++] = arr[begin2++];
}
}
void R_MergeSort(int* arr, int size)
{
int* tmp = (int*)malloc(sizeof(arr[0])*size);
if (NULL == tmp)
return ;
int gap = 1;
int left, mid, right;
int i;
while (gap < size)
{
for (i = 0; i < size; i += 2*gap)
{
left = i;
mid = left + gap;
if (mid > size){
mid = size;
}
right = mid + gap;
if (right > size){
right = size;
}
MergeData(arr, left, mid, right, tmp);
}
memcpy(arr, tmp, sizeof(arr[0]) * size);
gap *= 2;
}
free(tmp);
}
void printf_arr(int arr[],int size)
{
int i = 0;
for (; i < size; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
//int arr[10] = {2,7,1,4,3,9,6,0,5,8};
int arr[10] = { 4,4,6,7,3,0,9,3,5,2 };
int size = sizeof(arr) / sizeof(arr[0]);
R_MergeSort(arr, size);
printf_arr(arr, size);
system("pause");
return 0;
}