线性表的顺序表示相关真题

【2010年统考真题】设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0 1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。

(1)可将问题视为把数组ab转换成数组ba,a代表数组的前p个元素,b代表数组中余下的n-p个元素,先将a逆置,再将b逆置,最后将整个再逆置。
(2)算法描述如下:

void Reverse(int R[],int from,int to){
	int i,temp;
	for(i = 0;i<(to-from-1)/2;i++){
	temp = R[from+i];
	R[from+i] = R[to-i];
	R[to-i] = temp;
	}
}
void Converse(int R[],int n,int p){
	Reverse(R,0,p-1);
	Reverse(R,p,n-1);
	Reverse(R,0,n-1);
}

(3)时间复杂度为O(n),空间复杂度为O(1).
另解:借助辅助数组来实现。算法思想:创建大小为p的辅助数组S,将R中前p个整数依次暂存在S中,同时将R中后n-p个整数左移,然后将S中暂存的p个数依次放回到R中的后续单元。时间复杂度为O(n),空间复杂度为O§。

【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)因为是两个等长的升序序列,所以总的元素一定是偶数个,通过两两比较,找到第L/2个元素即可。
(2)算法如下:

//自己敲
void search(SeqList A,SeqList B,SeqList &C){
	int i,j,k=0
	while(i<A.length&&j<B.length){
		if(A.data[i]<=B.data[j])
		C.data[k++]=A.data[i++];
	else
		C.data[k++]=B.data[j++];
	}
	while(i<A.length)
		C.data[k++]=A.data[i++];
	while(j<B.length)
		C.data[k++]=B.data[j++];
	C.length=k;
	return k/2;  //返回中位数
}

(3)时间复杂度和空间复杂度都为O(n)

【2013年统考真题】已知一个整数序列A=(a0,a1,…an-1),其中0<=ai<=n。若存在ap1=ap2=…=apm=x 且m>n/2,则称x为A的主元素。例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输入该元素;否则输出-1。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
(1) 先遍历该数组,标记出可能成为主元素的元素,然后再次扫描,重新计数,判断该元素出现次数是否大于n/2.
第一步:选取候选的主元素。依次扫描所给数组中的每个整数,将第一个遇到的整数Num保存到c中,记录Num出现的次数为1;若遇到的下一个整数仍等于Num,则计数+1,否则计数-1;当计数减到0时,将遇到的下一个整数保存到c中,计数重新记为1,开始新一轮计数。
(2)算法代码如下:

int Majority(int A[],int n){
	int i,c,count=1;  //c用来保存候选主元素,count用来计数
	c=A[0];  //设置A[0]为候选主元素
	for(i=1;i<n;i++)
		if(A[i]==c)
			count++;
		else
			if(count>0)
				count--;
			else{
			c=A[i];
			count=1;
		}
	if(count>0)
		for(i=count=0;i<n;i++)
			if(A[i]==c)
				count++;
	if(count>n/2)
		return c;
	else
		return -1;
}

(3)时间复杂度为O(n),空间复杂度为O(1)

【2018年统考真题】给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
(1)从A[0]开始遍历A,若0 (2)算法代码如下:

int findMissMin(int A[],int n){
	int i,*B;
	B=(int *)malloc(sizeof(int)*n);  //分配空间
	memset(B,0,sizeof(int)*n);
	for(i=0;i<n;i++)
		if(A[i]>0&&A[i]<=n)
			B[A[i]-1]=1;
	for(i=0;i<n,i++)
		if(B[i]==0)
			break;
			return i+1;
}

(3)时间复杂度为O(n),空间复杂度为O(n)

【2020年统考真题】定义三元组(a,b,c)的距离D=|a-b|+|b-c|+|c-a|。给定3个非空整数集合S1、S2、S3,按升序分别存储在3个数组中。请设计一个尽可能搞笑的算法,计算并输出所有可能的三元组(a,b,c)中的最小距离。例如S1={-1,0,9},S2={-25,-10,10,11},S3={2,9,17,30,41},则最小距离为2。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
(1)暴力破解,直接三次for循环遍历,用公式带入。
(2)算法代码如下:

//暴力解法
void arr(int S1[],int S2[],int S3[]){
	int Length1 = sizeof(S1)/sizeof(S1[0]);
	int Length2 = sizeof(S2)/sizeof(S2[0]);
	int Length3 = sizeof(S3)/sizeof(S3[0]);
	int a,b,c;
	a = b = c;   //存储三元组
	int D=100000;  //给出一个超大的值
	for(int i=0;i<Length1;i++)
		for(int j=0;j<Length2;j++)
			for(int k=0;k<Length3;k++)
				int dis=abs(S1[i]-S2[j])+abs(S2[j]-S3[k])+abs(S3[k]-S1[i])
				if(dis<D){
					D=dis;
					a=S1[i];
					b=S2[j];
					c=S3[k];
				}
		print("%d",D);
		print("%d,%d,%d"a,b,c);
}

(3)时间复杂度为O(Length1Length2Length3),空间复杂度为O(1)

你可能感兴趣的:(算法,排序算法,数据结构)