码迷,mamicode.com
首页 > 编程语言 > 详细

算法第二章上机实践报告

时间:2018-10-21 16:00:21      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:递归   bsp   下标   复杂   需要   log   存储   时间   分治   

1.实践题目:两个有序序列的中位数

2.问题描述:

        输入一个n(0<N<=1e5),代表两个有序序列的长度,随后两行分别键入两个非降序序列,求出两个序列的合并后的中位数,此处中位数指有序序列中的第(N+1)/2个数,下标从0开始。

3.算法描述:

  采用分治法的思想,不断缩小问题的规模,最终合并子问题求解。

  每次分别求取每个序列的中位数,并比较中位数的大小,中位数较大的序列截取比该中位数小的一则的序列作为新的序列,中位数较小的序列截取比该中位数大的一侧的序列作为新的序列,比较新得到的两个序列的中位数,不断递归截取直到序列的规模足够小(本题取两个序列的长度分别为2时停止递归),对剩余的序列进行简单的排序操作后可得到最终答案,需要注意的是递归过程中应保持序列长度一致。

递归算法代码如下:

int findMid(int a[],int b[],int la,int ra,int lb,int rb){
    int mida=(la+ra)/2;
    int midb=(lb+rb)/2;    
    if(ra-la==0) {
        if(a[la]<b[lb]) return a[la];
        else return b[lb];
    }//当两个序列的初始长度都只为1时,特殊情况特殊处理
    if(ra-la==1) {
        int s[4];
        s[0]=a[la];
        s[1]=a[ra];
        s[2]=b[lb];
        s[3]=b[rb];
        sort(s,s+4);
        return s[1];
    }
    if(a[mida]<b[midb] ){
        if(ra-mida>midb-lb)//调整子序列长度
            return findMid(a,b,mida,ra,lb,midb+1);
        else
            return findMid(a,b,mida,ra,lb,midb);
    } 
    if(a[mida]>b[midb] ){
        if(mida-la<rb-midb)//调整子序列长度
            return findMid(a,b,la,mida+1,midb,rb);
        else
            return findMid(a,b,la,mida,midb,rb);
    }
}

4.算法分析

  时间复杂度:该算法在每步将问题分成规模为N/2的1个子问题,由求规模为N的两个有序序列的中位数转变为求规模为N/2的两个有序序列的中位数。在划分操作时,直接取下标进行划分,复杂度为O(1);在合并子问题时,只需对4个数进行简单的排序,时间复杂度可看做O(1),最终得出算法的时间复杂度为O(logn)。

  空间复杂度:因存储数组需要存储空间,规模为O(n),而排序时为了方便使用一个辅助数组,规模为O(1),最终得出空间复杂度为O (n)。

5.心得体会

  最初想到使用这个算法的时候,感觉实现起来还是挺容易的,但最终实现后发现只能处理部分问题,后来发现是没有注意调整子序列的长度,导致截取序列的时候出现错误。总体感觉还是对分治法的使用不够熟练,没能够调整好子问题规模的大小,希望能在今后的学习中不断加深对分治法的理解和使用。

算法第二章上机实践报告

标签:递归   bsp   下标   复杂   需要   log   存储   时间   分治   

原文地址:https://www.cnblogs.com/underdestiny/p/9825156.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!