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

#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函数所增加的代码

posted @ 2020-08-11 14:50  py佐料  阅读(158)  评论(0)    收藏  举报