【算法复习三】算法设计技巧与优化----算法设计技巧之中位数

题目:设计一个高效算法,求两个等长为L的升序序列AB 的中位数。

例如:S1=11,13,15,17,19

S2=2,4,6,8,20

S1S2的中位数是11

1)问题分析1

简单的算法是将两个升序序列归并排序,然后求其中位数

算法的时间复杂度和空间复杂度均为0(n)

2)问题分析2

利用归并排序的思想对AB的元素逐个访问,同时计数,当访问到第L个元素时即为所求。

算法时间、空间复杂度分别为O(n), O(1)

3)问题分析3

分别求AB的中位数ab

1)若a=b,则ab即为所求。

2)若a<b,舍弃a所在序列A中的较小一半,同时舍弃b中所在序列B较大一半,两者舍弃的元素个数相等,在保留的两个升序序列中继续求中位数ab

3)重复上述过程,直至两个序列中只含有一个元素为止,较小者即为所求。

算法时间、空间复杂度分别为O(log2`n), O(1)

综合算法

#include<iostream> using namespace std; int search1(int a[],int b[],int n) { int c[2*n]; int i=0,j=0; int count=0; while(i<n&&j<n) { if(a[i]<b[j]) c[count++]=a[i++]; else if(a[i]>b[j]) c[count++]=b[j++]; else { c[count++]=a[i]; ++i; ++j; } } while(i<n) { c[count++]=a[i++]; } while(j<n) { c[count++]=b[j++]; } return c[n-1]; } int search2(int a[],int b[],int n) { int i=0,j=0,count=1; while(count!=n) { if(a[i]<b[j]) ++i; else ++j; count++; } return a[i]<=b[j]?a[i]:b[j]; } int search3(int a[],int b[],int n) { int s1,e1,mid1,s2,e2,mid2; s1=0;//start e1=n-1;//end s2=0; e2=n-1; while(s1!=e1||s2!=e2) { mid1=(s1+e1)/2; mid2=(s2+e2)/2; if(a[mid1] == b[mid2]) return a[mid1]; if(a[mid1]<b[mid2])//分别考虑奇数和偶数,保持两数组个数相等 { if((s1+e1)%2 == 0) { s1=mid1;//舍弃a中间节点以前部分 e2=mid2;//舍弃b中间节点以后部分 } else //元素个数为偶数个 { s1=mid1+1; e2=mid2; } } else { if((s1+e1)%2 == 0) { e1=mid1;//舍弃a中间节点以前部分 s2=mid2;//舍弃b中间节点以后部分 } else //元素个数为偶数个 { e1=mid1; s2=mid2+1; } } } return (a[s1]<b[s2]?a[s1]:b[s2]); } int main() { int s1[5]={11,13,15,17,19}; int s2[5]={2,4,6,8,20}; cout<<"select which solution"<<endl; cout<<"1,归并"<<endl; cout<<"2,计数"<<endl; cout<<"3,中位数比较"<<endl; int n; cin>>n; switch(n) { case 1:cout<<search1(s1,s2,5)<<endl;break; case 2:cout<<search2(s1,s2,5)<<endl;break; case 3:cout<<search3(s1,s2,5)<<endl;break; default :break; } return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值