归并排序算法(C语言)

归并排序:
思想:利用将两个的有序数据序列合并成一个新的有序数据序列,在如何分成两个有序数据的问题下,采用分治算法。


时间复杂度:O(n*logn)
空间复杂度:O(n)
是否稳定: 稳定


这里写图片描述


代码实现如下:

1。递归式

#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <string.h>
#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 <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <string.h>
#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;
}

猜你喜欢

转载自blog.csdn.net/romantic_c/article/details/79895622