合并排序(C语言实现)

 更新时间:2013年02月21日 09:27:16   作者:  
递归算法是把一个问题分解成和自身相似的子问题,然后再调用自身把相应的子问题解决掉。这些算法用到了分治思想。

其基本模式如下:

分解:把一个问题分解成与原问题相似的子问题

解决:递归的解各个子问题

合并:合并子问题的结果得到了原问题的解。

现在就用递归算法,采用上面的分治思想来解合并排序。

                      合并排序(非降序)

分解:把合并排序分解成与两个子问题

伪代码:

复制代码 代码如下:

MERGE_SORT(A, begin, end)

if begin < end

   then mid<- int((begin + end)/2)

           MERGE_SORT(A, begin, mid)

           MERGE_SORT(A, mid+1, end)

           MERGE(A, begin, mid, end)


解决:递归的解各个子问题,每个子问题又继续递归调用自己,直到"begin<end"这一条件不满足时,即"begin==end"时,此时只有一个元素,显然是有序的,这样再进行下一步合并。


合并:合并的子问题的结果有个隐含问题,即各个子问题已经是排好序的了(从两个氮元素序列开始合并)。做法是比较两个子序列的第一个元素小的写入最终结果,再往下比较,如下图所示:

        图中:待排序数组为2 4 6  1 3 5

        把2 4 6和 1 3 5 分别存到一个数组中,比较两个数组的第一个元素大小小者存于大数组中,直到两小数组中元素都为32767.

        这里32767 味无穷大,因为 c语言中  int类型是32位,表示范围是-32768-----32768。用无穷大作为靶子可以减少对两个小数组是否为空的判断,有了靶子,直接判断大数组元素个数次就排完了。 

     在整个过程中执行过程示如下图:

分解+执行时自上向下,合并时自下向上。

 代码奉上:

复制代码 代码如下:

#include <stdio.h>

void MERGE(int *A, int b, int m, int e)

{      

        int l = m-b+1, r = e-m, i;

        int L[l+1], R[r+1];

        for(i=0; i< l; i++)

        {

            L[i] = A[b+i];

        }

        for (i=0; i< r; i++)

        {

            R[i] = A[m+i+1];

        }

        L[l] = 32767;

        R[r] = 32767;

        l = 0;

        r = 0;

        for(i=0; i< e-b+1; i++)

        {

            if(L[l] < R[r])

            {

                A[b+i] = L[l];

                l ++;

            }

            else            {

                A[b+i] = R[r];

                r ++;

            }

        }

}

 

void MERGE_SORT(int *A, int b, int e)

{

        if(b < e)

        {

            int m = (b + e) / 2;

            MERGE_SORT(A, b, m);

            MERGE_SORT(A, m+1, e);

            MERGE(A, b, m, e);

        }

}

int main()

{

        int A[500];

        int lens, i;

        printf("Please Enter the lenghth of array:");

        scanf("%d", &lens);

 

        printf("Please Enter the elements of the array:");

        for(i=0; i< lens; i++)

            scanf("%d", &A[i]);

 

        MERGE_SORT(A, 0, lens-1);

 

        printf("the result of the sort is:\n");

        for(i=0; i< lens; i++)

        {

            printf("%d ", A[i]);

        }

        return 0;

}

相关文章

  • C语言运用函数的递归实现汉诺塔

    C语言运用函数的递归实现汉诺塔

    递归(recursive)函数是“自己调用自己”的函数,无论是采用直接或间接调用方式。间接递归意味着函数调用另一个函数(然后可能又调用第三个函数等),最后又调用第一个函数。因为函数不可以一直不停地调用自己,所以递归函数一定具备结束条件
    2022-07-07
  • C#中委托的基本用法总结

    C#中委托的基本用法总结

    以下是对C#中委托的基本用法进行了详细的总结分析,需要的朋友可以过来参考下。希望对大家有所帮助
    2013-09-09
  • C语言中的文件读写fseek 函数

    C语言中的文件读写fseek 函数

    这篇文章主要介绍是我是C语言中的文件读写fseek 函数的相关资料,fseek 函数用来移动文件流的读写位置;就好比播放器,可以直接拖拽到精彩的时间点一样,下面我们就来详细介绍该内容吧,感兴趣的小伙伴可以参考一下
    2021-10-10
  • 64位linux 编译c提示gnu/stubs-32.h:No such file or directory的解决方法

    64位linux 编译c提示gnu/stubs-32.h:No such file or directory的解决方法

    这篇文章主要介绍了64位linux 编译c提示gnu/stubs-32.h:No such file or directory的解决方法,需要的朋友可以参考下
    2020-03-03
  • C++中如何调用C语言的代码实现

    C++中如何调用C语言的代码实现

    这篇文章主要介绍了C++中如何调用C语言的代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 浅谈c语言中类型隐性转换的坑

    浅谈c语言中类型隐性转换的坑

    下面小编就为大家带来一篇浅谈c语言中类型隐性转换的坑。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • 一道超经典的C++结构体的题目

    一道超经典的C++结构体的题目

    以下小编就为大家介绍一道超经典的关于C++结构体的题目。需要的朋友可以过来参考下
    2013-09-09
  • C++实现和电脑对战三子棋实例

    C++实现和电脑对战三子棋实例

    大家好,本篇文章主要讲的是C++实现和电脑对战三子棋实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C语言按关键字搜索文件夹中文件的方法

    C语言按关键字搜索文件夹中文件的方法

    这篇文章主要介绍了C语言按关键字搜索文件夹中文件的方法,涉及C语言文件操作及字符串查找的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C++11新特性之随机数库(Random Number Library)详解

    C++11新特性之随机数库(Random Number Library)详解

    相对于C++11之前的随机数生成器来说,C++11的随机数生成器是复杂了很多,下面这篇文章主要给大家介绍了关于C++11新特性之随机数库(Random Number Library)的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论