算法第二章上机实践报告

 
一、实践题目
7-3 两个有序序列的中位数 (20 分)

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0​​,A1​​,,AN1​​的中位数指A(N1)/2​​的值,即第(N+1)/2⌋个数(A0​​为第1个数)。

二、问题描述

输入格式:

输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的并集序列的中位数。

输入样例1:

5
1 3 5 7 9
2 3 4 5 6

输出样例1:

4

输入样例2:

6
-100 -10 1 1 1 1
-50 0 2 3 4 5

输出样例2:

1

 

三、算法描述

采用分治与递归策略,二分法每次将问题规模减半,然后对问题进行递归处理,在进行递归的过程中对可能出现特殊的情况,就特殊安排处理。

代码如下:
#include<iostream>
using  namespace std;
 
 
int MidSerch(int a[], int b[], int la, int ra, int lb, int rb) {
int ma = (la + ra) / 2;
int mb = (lb + rb+1) / 2;
if (la == ra&&lb != rb) {
if (a[la] > b[rb])return b[rb];
else return a[la];
}
if (lb == rb&&la != ra) {
if (b[lb] > a[ra])return a[ra];
else return b[lb];
}
 
if (la == ra&&lb == rb) {
if (a[la] > b[lb])return b[lb];
else return a[la];
}
else
{    if (la == ra - 1 && lb == rb - 1)
    {
ma = (la + ra) / 2;
mb = (lb + rb) / 2;
    }
if (a[ma]==b[mb])
{
return a[ma];
}
else if (a[ma] > b[mb]) {
MidSerch(a, b, la, ma ,mb, rb);
}
else{
MidSerch(a, b, ma, ra, lb, mb);
}
 
}
}
 
 
int main() {
int n;
cin >> n;
    int *a = new int[n];
int *b = new int[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
cin >> b[i];
}
 
cout<<MidSerch(a, b, 0, n - 1, 0, n - 1);
 
system("pause");
}

四、算法时间及空间复杂度分析

由于采用递归二分策略,每次将问题分成规模减半的子问题(即所说的不断二分),所以消耗的时间是(时间复杂度)O(logN),再加上特殊
情况的比较和比较所用的常数时间,时间复杂度还是为O(logN)。对于空间复杂度,由于只开辟了几个变量的地址和数据,所以空间复杂度为O(1);

五、心得体会
一开始使用了vector来排序,没考虑时间复杂度的问题,虽然过了,后来和组员讨论,使用了分治和递归的算法,从中温习了许多算法的知识,收获很多。

 

posted @ 2018-10-21 22:49  王浩鹏  阅读(278)  评论(0)    收藏  举报