数据结构 王道 算法大题 第二章 线性表 C++编程实现

数据结构 第二章 线性表

2.2 线性表的顺序表示

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

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
//从顺序表中删除具有最小值的元素。由函数返回被删元素的值。空出的位置由最后一个元素填补。若顺序表为空,则显示出错信息并退出运行。
bool del_min(SqList &a,int &min){
	if(a.length==0) return false;
	int pos=0;
	min=a.data[0];
	for(int i=0;i<a.length;++i){
		if(a.data[i]<min){
			min=a.data[i];
			pos=i;
		}
	}
	a.data[pos]=a.data[a.length-1];
	a.length--;
	return true;
}

int main(){
	SqList a;
	int min=0;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	del_min(a,min);
	printf("%d\n",min);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
} 

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

#include<stdio.h>
#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;

void swap(int &c,int &d){
	int temp=0;
	temp=c;
	c=d;
	d=temp;
}

bool Inverse(SqList &a){
	if(a.length==0) return false;
	int i=0,j=a.length-1;
	while(i<j){
		swap(a.data[i++],a.data[j--]);
	}
	return true;
}

int main(){
	SqList a;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	Inverse(a);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}

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

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
void del_x(SqList &a,int x){
	int k=0;
	for(int i=0;i<a.length;i++){
		if(a.data[i]!=x){
			a.data[k]=a.data[i];
			k++;
		}
	}
	a.length=k;
}

int main(){
	SqList a;
	int x=19;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	del_x(a,x);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}
  1. 5.从有序(无序也可以)顺序表中删除,其值在给定值s与t之间要求s小于t的所有元素。若s或t取值不合理或顺序表为空。则显示出错信息并退出运行。
    测试数据:107 26 32 23 64 78 96 -1
#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
bool del_s_t(SqList &a,int s,int t){
	if(s>=t||a.length==0) return false;
	int k=0;
	for(int i=0;i<a.length;i++){
		if(a.data[i]<s||a.data[i]>t){
			a.data[k]=a.data[i];
			k++;
		}
	}
	a.length=k;
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	int s=20,t=65;
	del_s_t(a,s,t);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}

6.从有序顺序表中删除所有其值重复的元素。使表中所有元素的值均不同。
//我的代码对无序表同样适用
测试数据:65 65 19 32 32 32 65 23 64 3 19 9 3 -1

include<stdio.h>
#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
void del_same(SqList &a){
	int k=0;
	for(int j=0;j<a.length;j++){
		k=j+1;
		for(int i=j+1;i<a.length;i++){
			if(a.data[i]!=a.data[j]){
				a.data[k]=a.data[i];
				k++;
			}
		}
		a.length=k;
	}
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	del_same(a);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}

7.将两个有序顺序表。合并为一个新的有序顺序表。并由函数返回结果顺序表。
//测试数据:2 4 6 8 10 14 16 19 20 -1
// 1 3 5 7 9 10 16 -1

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList; 
void merge(SqList a,SqList b,SqList &c){
	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 if(a.data[i]==b.data[j]){
			c.data[k++]=a.data[i++];
			c.data[k++]=b.data[j++];
		}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;
}

int main(){
	SqList a,b,c;
	a.length=0;
	b.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	for(int i=0;i<maxsize;++i){
		scanf("%d",&b.data[i]);
		if(b.data[i]==-1) break;
		b.length++;
	}
	merge(a,b,c);
	for(int i=0;i<c.length;++i){
		printf("%d ",c.data[i]);
	}
	return 0;
}

8.已知在一维数组A[m+n]中存放两个线性表(a1,a2,a3…,am)和(b1,b2,b3,b4…,bn)。试编写一个函数。将数组中两个顺序表的位置互换。
即将 (b1,b2,b3,b4…,bn)放在 (a1,a2,a3…,am)的前面。
//测试数据: 2 4 6 8 10 14 16 19 20 -1

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
void swap(int &a,int &b){
	int temp=a;
	a=b;
	b=temp;
}
bool reverse(SqList &a,int s,int t){
	if(a.length==0||s>t) return false;
	int i=s,j=t;
	while(i<j){
		swap(a.data[i++],a.data[j--]);
	}
	return true;
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	int m=3,n=6;
	reverse(a,0,m+n-1);
	reverse(a,0,n-1);
	reverse(a,n,m+n-1);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}

9.线性表(a1,a2,a3…,an)中的元素递增有序写,按顺序存储于计算机内,要求设计一个算法完成,用最少时间在表中查找数值为x的元素。若找到则将其与后继元素位置相交换。若找不到,则将其插入。表中,并将表中元素仍递增有序。
//测试数据:2 4 6 8 10 14 16 19 20 -1 插入10

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
int binary_search(SqList a,int x){  //折半查找,时间最短 
	int low=0,high=a.length-1,mid;
	while(low<=high){
		mid=(low+high)/2;
		if(a.data[mid]==x) return mid;
		else if(a.data[mid]>x){
			high=mid-1;
		}else{
			low=mid+1;
		}
	}
	return -1;
}
void ExchangeInsert(SqList &a,int x){
	int t=binary_search(a,x),temp,i;
	if(t!=-1&&t!=a.length-1){
		temp=a.data[t];
		a.data[t]=a.data[t+1];
		a.data[t+1]=temp;
	}
	if(t==-1){
		for(i=a.length-1;a.data[i]>x;i--){
			a.data[i+1]=a.data[i];
		}
		a.data[i+1]=x;
		a.length++;
	}
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	ExchangeInsert(a,10);
	for(int i=0;i<a.length;++i){
		printf("%d ",a.data[i]);
	}
	return 0;
}

10.和第八题算法一致
11.【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.说明你所设计算法的时间复杂度和空间复杂度。

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;
//这个算法有瑕疵,只适用于没有相同元素的两个序列  改正的方法很简单  
int mid_num(SqList a,SqList b){
	if(a.length!=b.length) return -1;
	int i=0,j=0,k=0,mid;
	while(i<a.length&&j<b.length&&k!=a.length){
		if(a.data[i]<=b.data[j]){ //改正 把相等情况单领出来再改下判别条件
			mid=a.data[i++];
			k++;
		}else{
			mid=a.data[j++];
			k++;
		}	
	}
	while(i<a.length&&k!=a.length){
		mid=a.data[i++];
		k++;
	}
	while(j<b.length&&k!=a.length){
		mid=a.data[j++];
		k++;
	}
	return mid;
}

int main(){
	SqList a,b;               
	a.length=0;
	b.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	for(int i=0;i<maxsize;++i){
		scanf("%d",&b.data[i]);
		if(b.data[i]==-1) break;
		b.length++;
	}
	printf("%d ",mid_num(a,b));
	return 0;
} 

12.【2013年统考真题】已知一个整数序列A=(a0,a1,…an-1)其中,0<=ai<n,若存在ap1=ap2=ap3=…=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中没有主元素.

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;

int majority(SqList a){
	int i=0;
	int b[a.length]={0};
	while(i<a.length){
		b[a.data[i++]]++;
	}
	int m=b[0],maj=0;
	for(int j=1;j<a.length;j++){
		if(b[j]>m){
			m=b[j];
			maj=j;
		}
	}
	if(m> a.length/2){
		return maj;
	}	
	return -1;
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	printf("%d\n",majority(a));
	return 0;
} 

该算法时间复杂度为O(n),加了一个辅助数组b,空间复杂度为O(n);
13.给定一个含n个整数的数组。请设计一个在时间上尽可能高效的算法。找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1。数组{1,2,3}中未出现的最小正整数是4.要求:
1。给出算法的基本设计思想。
2。根据设计思想,采用C或C++语言描述算法。关键之处给出注释。
3。说明你所设计算法的时间复杂度和空间复杂度。

算法设计思想和上一题类似

#include<stdio.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;

int min_z(SqList a){
	int i=0;
	int b[maxsize]={0};
	while(i<a.length){
		if(a.data[i]>0){
			b[a.data[i]]++;
		}
		i++;
	}
	for(int j=1;j<maxsize;j++){
		if(b[j]==0){
			return j;
		}
	}	
	return -1;
}

int main(){
	SqList a;
	a.length=0;
	for(int i=0;i<maxsize;++i){
		scanf("%d",&a.data[i]);
		if(a.data[i]==-1) break;
		a.length++;
	}
	printf("%d\n",min_z(a));
	return 0;
} 

该算法时间复杂度为O(n),加了一个辅助数组b,空间复杂度为O(n);
14.定义域三元组(a,b,c)的距离D=|a-b|+|b-c|+|c-a|。给定3个非空整数集合S1,S2和S3。按升序分别存储在三个数组中。请设计一个尽可能高效的算法。计算并输出所有可能的三元组(a,b,c)中的最小距离。要求:
1给出算法的基本设计思想。
2.根据设计思想,采用c语言或c加加语言描述算法。关键之处给出注释。
3.说明你所设计算法的时间复杂度和空间复杂度。

#include<stdio.h>
#include<math.h>

#define maxsize 50
typedef struct{
	int data[maxsize];
	int length;
}SqList;

void min_dis(SqList a,SqList b,SqList c){
	int i=0,j=0,k=0,d,min=65536,min_a,min_b,min_c;
	while(i<a.length&&j<b.length&&k<c.length){
		d=abs(a.data[i]-b.data[j])+abs(b.data[j]-c.data[k])+abs(c.data[k]-a.data[i]);
		if(d<min){
			min=d;
			min_a=a.data[i];
			min_b=b.data[j];
			min_c=c.data[k];
		}
		if(a.data[i]<b.data[j]&&a.data[i]<c.data[k]){
			i++;
		}else if(b.data[j]<a.data[i]&&b.data[j]<c.data[k]){
			j++;
		}else{
			k++;
		}	
	}
	printf("%d (%d,%d,%d)\n",min,min_a,min_b,min_c);
}

最好时间复杂度为O(min(l,m,n));最坏时间复杂度为O(l+m+n);
空间复杂度为O(1);

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的喵~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值