2020考研数据结构 408算法2011年真题

问题:

一个长度为L(L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数为11,。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求:

     (1)给出算法的基本设计思想。

     (2)根据设计思想,采用 C 或C++或java语言描述算法,关键之处给出注释

     (3)说明你所设计算法的时间复杂度和空间复杂度。


1.

   设A序列的中位数是a,B序列的中位数是b

第一步:若a=b,则a=b即为所求

第二步:若a<b,舍弃A的中位数的前一部分,舍弃B的中位数的后一部分,且舍弃的个数相等

第三步: 若a>b,舍弃B的中位数的后一部分,舍弃A的中位数的前一部分,且舍弃的个数相等


2.

#include<stdio.h>
#define maxSize 100
typedef struct Sqlist{
	int data[maxSize];
	int length;
}Sqlist;

int Sequencemedian(Sqlist &A,Sqlist &B,int n){
	int s1=0,d1=n-1,s2=0,d2=n-1,m1,m2;
	//分别表示A序列的首位数和末位数,B序列的首位数和末位数
	while(s1!=d1||s2!=d2){//保证最终只剩下一个元素 
		m1=(s1+d1)/2;
		m2=(s2+d2)/2;
		if(A.data[m1]==B.data[m2])
			return A.data[m1];
		if(A.data[m1]<B.data[m2]){
			if((s1+d1)%2==0)//个数是奇数个 
			{
				s1=m1;
				d2=m2; 
			} 
			else{//个数是偶数个
				s1=m1+1;
				d2=m2; 
				
			}
		}
		else {
			if((s2+d2)%2==0){//个数是奇数个 
				d1=m1;
				s2=m2;
			} else{//个数是偶数个 
				d1=m1;
				s2=m2+1;
			}
		}
	
			
	} 
		return A.data[s1]<B.data[s2] ?A.data[s1]:B.data[s2];
	
}
int initSqlist(Sqlist &L){
	int n;
	 printf("顺序表要输入的个数:");
	 scanf("%d",&n);
	 printf("\n");
	 L.length=n;
	 for(int i=0;i<n;i++){
	 	printf("输入第%d个元素:",i+1);
	 	scanf("%d",&L.data[i]);
	 }
	 return n;
}
void display(Sqlist &L)
{
	for(int i=0;i<L.length;i++)
  	{
    	printf("第%d的元素为:%d\n",i+1,L.data[i]);
	}
	 
} 
int main(){
	Sqlist A;
	Sqlist B;
	int n=initSqlist(A);
	initSqlist(B);
	int p=Sequencemedian(A,B,n); 
	printf("AB序列的中位数%d",p);
	return 0;
} 

3.时间复杂度:O(log2 n)。因为每次都是n个数取一半

空间复杂度:O(1)

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值