常见排序算法——归并排序

基本思想:
将待排序的元素序列分成两个长度相等的子序列,对每一个子序列排序,
然后将他们合并成一个序列。合并两个子序列的过程称为二路归并.

由于归并排序不依赖于待排序元素序列的初始输入状态,每次划分时两个
子序列的长度基本一致,所以归并排序的最好、最差和平均时间复杂度均
为O(n*log2n )
空间复杂度为:O(n)
它是一种稳定的排序算法

void _MergeData(int* array, int left, int mid, int right, int* tmp)
{
    //区间为左闭右开
    int leftL = left;
    int rightL = mid;
    int leftR = mid;
    int rightR = right;
    int Index = left;

    while (leftL < rightL && leftR < rightR)
    {
        if (array[leftL] < array[leftR])
            tmp[Index++] = array[leftL++];
        else
            tmp[Index++] = array[leftR++];
    }

    while (leftL < rightL)
    {
        tmp[Index++] = array[leftL];
        ++leftL;
    }

    while (leftR < rightR)
    {
        tmp[Index++] = array[leftR];
        ++leftR;
    }
}
void _MergeSort(int* array, int left, int right, int* tmp)
{
    //保证区间内至少有一个元素,否则会造成栈溢出
    if (right - left > 1)
    {
        int mid = left + (right - left) / 2;

        //先对左边序列排序
        _MergeSort(array, left, mid, tmp);

        //再对右边序列排序
        _MergeSort(array, mid, right, tmp);

        //最后将左右序列进行归并
        _MergeData(array, left, mid, right, tmp);

        //将元素拷贝回旧空间
        memcpy(array + left, tmp + left, (right - left) * sizeof(array[0]));

    }
}
void MergeSort(int* array, int size)
{
    int* tmp = (int *)malloc(sizeof(int)* size);
    if (NULL == tmp)
    {
        assert(0);
        return;
    }
    _MergeSort(array, 0, size, tmp);

    free(tmp);
}

猜你喜欢

转载自blog.csdn.net/weixin_41289858/article/details/80583167