• 算法——归并排序原理及操作


    #include <iostream>

    #include <cstdio>

    using namespace std;

    //归并排序

    /*

    原理:分而治之,然后合之。

    一分为二,然后从两个数组中头部依次拿出较小的值放入辅助数组中,从而达到排序的目的。

    */

    int  a[9]={0,1,54,77,24,97,32,8,21};

    int t[9];

    void fun(int l,int r)

    {

        if(l==r) return;    //一开始给出递归停止的条件

        int mid=(l+r)/2;    //由于int的截断,无论奇偶都是适用的

     

    /*  理解递归函数,要从功能单元的角度出发。

        在这里fun函数功能单元就是:一分为二,然后从两个数组的头部按大小顺序拿元素放入辅助数组中。

        所以理解的时候可以先去掉这两行递归的代码,理解fun实现的功能。

        然后再利用递归的思想:

        要处理大的问题,就把它分解成为问题解决模式相同的子问题,在这里表现为:要让整个数组

        排好序,就得先一分为二,按序取出。可是要保证第一次按序取出后数组就有序,就得保证

        第一次分成的两个数组本来就排好了序。(这一点自行验证),为了保证这一点,就需要在“合”之前递归。(因为这是fun的功能)

        这样一来就确定了递归代码的位置。

    */

        fun(l,mid);

        fun(mid+1,r);

        int p=l,q=mid+1,f=l;    //f用来记录一开始l的值(后面l会变)

        while(p<=mid && q<=r)       //从两个分好的数组头部开始拿元素

        {

            if(a[p]<=a[q])

                t[l++]=a[p++];

            if(a[q]<a[p])

                t[l++]=a[q++];

        }

        while(p<=mid)       //如果左边数组没拿完

            t[l++]=a[p++];

        while(q<=r)

            t[l++]=a[q++];  //如果右边数组没拿完

        for( ;f<=r;f++)  //从辅助数组赋值回去

            a[f]=t[f];

    }

    int main()

    {

        fun(1,8);

        for(int i=1;i<=8;i++)

            cout<<a[i]<<" ";

        return 0;

    }

    备注

    1.以上代码中,fun函数里的最后一步:t数组覆盖a数组是必不可少的,不能省略这一步并且认为函数运行完后的t数组就是排好序的数组,这是错误的观点。另外,t++,p++,q++在上下两次的衔接(同时从两个数组中拿和他下面的从一个没拿完的数组)过程中并没有漏掉上一次的最后一个p/q。

    2.红色部分代码,是添加递归思想后fun函数所增加的代码

    这篇文章,是又一个故事的结束...
    lazy's story is continuing.
  • 相关阅读:
    2021.8.2—2021.8.8
    2021.7.29
    2021.7.27
    2021.7.26
    GC日志分析
    学习类加载机制笔记
    4、SpringCloud停更说明
    3、SpringCloudAlibaba版本选择
    京东、阿里的微服务架构
    nacos集群安装
  • 原文地址:https://www.cnblogs.com/Hello-world-hello-lazy/p/13475577.html
Copyright © 2020-2023  润新知