2.2顺序表应用题

1、从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。

//表为空显示出错并退出。查找最小值元素,记住最小值的值和位序,删除最小值并用最后一个值填补
bool Del_Min(sqList &L,ElemType &value){
	if(L.length==0)
	return false;
	value=L.data[0];
	int pos=0;
	for(int i=1;i<L.length;i++)
	if(L.data[i]<value){
	value=L.data[i];
	pos=i;
	}
	L.data[pos]=L.data[L.length-1];
	L.length--;
	return true;
}

 

2、设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)

//for循环遍历,扫描前半部分L.length/2,用L.data[L.length-1-i]替换L.length[i]
void Reverse(SqList &L){
	Elemtype temp;
	for(i=0;i<L.length/2;i++){
	temp=L.data[i];
	L.data[i]=L.data[L.length-1-i];
	L.data[L.length-1-i]=temp;
	}
}

 

3、对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素。

解法一:循环遍历所有元素,统计不等于x的元素k,最后将不等于x的元素L.data[i]赋值于L.data[k]
void del_x_1(SqList &L,ElemType x){
	int k=0;
	for(i=0;i<L.length;i++)
	if(L.data[i]!=x){
	L.data[k]=L.data[i];
	k++
	}
	L.length=k;
}
解法二:循环遍历与x相等的元素个数k,将不等于x的元素向前移动k个位置
void del_x_2(SqList &L,ElemType x){
	int k=0,i=0;
	while(i<L.length){
	if(L.data[i]==x)
	k++;
	else
	L.data[i-k]=L.data[i];
	i++;
	}
	L.length=L.length-k;
}

 

4、从有序顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示错误信息并退出运行。

4//检测s>t或顺序表为空,返回return false;
for循环遍历,寻找大于等于s的第一个元素,再寻找大于t的第一个元素(最后一个删除的元素的下一个元素)
将属于s与t之间元素删除,顺序表往前移动
bool Del_s_t2(SqList &L,ElemType s,ElemType t){
	int i,j;
	if(s>=t||L.length==0)
	return false;
	for(i=0;i<L.length&&L.data[i]<s;i++)//确定s之前的元素
	if(i>=L.length)
	return false;
	for(j=i;j<L.length&&L.data[j]<=t;j++)//最后一个t
	for(;j<L.length;i++,j++)
	L.data[i]=L.data[j];//前移
	L.length=i;
	return true;
}

 

5、从顺序表中删除其值在给定值s与t之间(包含s和t,要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行

如果s>=t或为空显示出错,扫描L,s与t之间元素为k个,不在s与t之间的元素前移k个位置,否则执行k++
bool Del_s_t(SqList &L,ElemType s,ElemType t){
	int i,k=0;
	if(L.length==0||s>=t)
	return false;
	for(i=0;i<L.length;i++){
	if(L.data[i]>=s&&L.data[i]<=t)
	k++;
	else
	L.data[i-k]=L.data[i];
	}
	L.length-=k;
	return true;
}

 

6、从有序表中删除所有其值重复的元素,使表中所有元素的值均不同

是有序表,相同元素在连续的位置上,
bool Delete_Same(SeqList &L){
	if(L.length==0)
	return false;
	int i,j;
	for(i=0,j=1;j<L.length;j++)
	if(L.data[i]!=L.data[j])
	L.data[++i]=L.data[j];
	L.length=i+1;
	return true;
}

 

7、将两个有序顺序表合并成为一个新的有序顺序表,并由函数返回结果顺序表

//按顺序取下两个顺序表表头较小的结点存入新的顺序表,然后看哪个表还有剩余,将剩下的部分加到新的顺序表之后。
经典题
bool Merge(SeqList A,SeqList B,SeqList &C){
	if(A.length+B.length>C.maxSize)
	return false;
	int i=0,j=0,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 true;
}

 

8、

先将数组的全部元素逆置,再对前n个元素和后m个元素分别使用逆置算法
typedef int DataType;
void Reverse(DataType A[],int left,int right,int arraySize){
	if(left>=rigth||rigth>=arraySize)
	return;
	int mid=(left+rigth/2);
	for(int i=0;i<=mid-left;i++){
	Datatype temp=A[left+i];
	A[left+i]=A[rigth-1];
	A[right-i]=temp;
	}
}
void Exchange(DataType A[],int m,int n,int arraySize){
	Reverse(A,0,m+n-1,arraySize);
	Reverse(A,0,n-1,arraySize);
	Reverse(A,n,m+n-1,arraySize);
}

 

9、

折半查找,查找,交换,插入
void SearchExchangeInsert(ElemType A[],ElemType x){
	int low=0,high=n-1,mid;
	while(low<=high){
	mid=(high+low)/2;
	if(A[mid]==x)break;
	else if(A[mid]<x)low=mid+1;
	else high=mid-1;
	}
	if(A[mid]==x&&mid!=n-1){
	t=A[mid];A[mid]=A[mid+1];A[mid+1]=t;
	}
	if(low>high){
	for(i=n-1;i>high;i--)
	A[i+1]=A[i];
	A[i+1]=x;
	}

}

10.设将n(n>1)个整数存放到一维数组R中,设计一个算法,将R中的序列循环左移P(0<P<n)个位置,即将R中的数据由{X0,X1,…,Xn-1}变换为{Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1}

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);
}

11、一个长度为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的中位数。

(次优)(次优是考研的优先选择,只扣一分且易懂)

//数列a,b元素个数len相同,比较len-1次
int findmid2 ( int* a, int* b, int len ) {
	int i = 0, j = 0, k = 0;

	for ( ; k < len-1; k++ ) {
		if ( a[i] < b[j] ) {
			i++;
		}
		else {
			j++;
		}
	}

	return (a[i] < b[j])? a[i]: b[j];
}

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

 

12、

已知一个整数序列A=(a0,a1,…,an-1),其中0≤ai<n(0≤i<n)。若存在ap1=ap2=…=apm=x且m>n/2(0≤pk<n,1≤k≤m),则称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。

(次优)

#include"head.h";
int main(){
	int n;
	printf("请输入数组长度:");
	scanf_s("%d", &n);
	int counter[100];//申请一个计数的数组,该数组是计量每个数的重复次数
	for (int i = 0; i < n; i++) {
		counter[i] = 0;//初始化计数数组
	}
	int s[100];
	printf("请输入数组元素:");
	for(int j=0;j<n;j++){     //核心
		scanf_s("%d",&s[j]);
		counter[s[j]]++;
	}
	int  p= 1;
	for(int i=0;i<n;i++){
		if (counter[i] > n / 2) {
			p = 0;
			printf("主元素为%d", i);
			break;
		}		
	}
	if (p)
		printf("-1\n");
	return 0;
}

13、给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5, 3, 2, 3}中未出现的最小正整数是1;数组{1, 2, 3}中未出现的最小正整数是4。

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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值