排序算法之归并排序讲解

描述

今天我们继续来讲排序算法,归并排序,难度一般,但是效率也还不错。

老规矩,先搞清楚原理,再写代码。

归并排序分为两个步骤,先是拆分,然后再合并。

我们先来看下合并。

假设有两个有序的数组,一个是1、3、5,一个是2、4、6、8,把他们合并成一个有序的数组。

MID  

这个操作应该极其简单。两个下标,一块新的内存。

1和2比较,1小,把1放在新的内存中,x向后走。

2和3比较,2小,把2放在内存中,y向后走。

下面依次把4和5放进去,最后x达到了末尾,y变成了6的下标,那就把y后面的数据全部放进去就行。

这个过程就是合并。

那么问题又来了,去哪找两个有序的数组。

这个就需要对数组做拆分。

MID  

比如数组有8个元素,我们先从中间拆开,得到两个数组,每个4个元素。

但是这两个数组也不是有序的,于是对两个数组继续拆分。

左边是两个数组,每个数组两个元素,右边也一样。

这样还不够,继续拆分,最后得到的数组只有一个元素。

如果一个数组只有一个元素,那么它一定就是有序的。

这个过程就需要用到递归。

过程清楚了,下面就是用代码来实现它。

 

#include 
#include 
#include 


#define SIZE     100000


void merge(int *a, int start, int mid, int end)
{
    int left_len = mid - start + 1;
    int right_len = end - mid;


    int *L = (int *)malloc(sizeof(int) * left_len);
    int *R = (int *)malloc(sizeof(int) * right_len);


    int i, k = start, j;
    for (i = 0; i < left_len; i++, k++)
    {
        L[i] = a[k];
    }


    for (i = 0; i < right_len; i++, k++)
    {
        R[i] = a[k];
    }


    for (i = 0, j = 0, k = start; i < left_len && j < right_len; k++)
    {
        if (L[i] > R[j])
        {
            a[k] = R[j++];
        }
        else
        {
            a[k] = L[i++];
        }
    }


    if (i < left_len)
    {
        for (; i < left_len; i++, k++)
        {
            a[k] = L[i];
        }
    }


    if (j < right_len)
    {
        for (; j < right_len; j++, k++)
        {
            a[k] = R[j];
        }
    }


    free(L);
    free(R);
}


void merge_sort(int *a, int start, int end)
{
    if (start >= end)
        return;


    int mid = (end + start) / 2;


    merge_sort(a, start, mid);
    merge_sort(a, mid + 1, end);


    merge(a, start, mid, end);
}


int main()
{
    int num, arr[SIZE] = {0}, i;


    //随机产生数组
    srand(time(NULL));
    for (i = 0; i < SIZE; i++)
    {
        arr[i] = rand() % 100;
    }


    merge_sort(arr, 0, SIZE - 1);


    for (i = 0; i < SIZE; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("
");


    return 0;
}
归并排序难度不大,但是和堆排序一样,数据越多,顺序越乱,效率越高。

当然,归并排序的缺点就是,需要更多的内存空间。

 




审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分