顺序表算法练习

news2024/12/25 9:38:12

一.顺序表基础算法

1.说明

博主这里是算法练习,帅气的读者来这里默认已经知道了它,这里主要是针对408考研真题中关于线性表的算法题进行编写。第一部分是根据课本编写线性表的基本函数,剩下四个部分是针对考研真题的算法练习。

2.C语言代码

这里使用C语言实现课本要求的基本算法,一=以一个学生成绩单为例:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MaxSize 50                //这里只是演示,我们假设这里最多存五十个学生信息

//定义学生结构
typedef struct {
	char name[20];              //姓名
	char tel[15];               //电话
	char id[10];               //学号,这个是主键
	int  grade;               //分数
} Elemtype;

//声明使用顺序表
typedef struct {
	/*这里给数据分配内存,可以有静态和动态两种方式,这里采用动态分配*/
	Elemtype  *data;            //存放线性表中的元素是Elemtype所指代的学生结构体
	int length;                 //存放线性表的长度
} SqList;						//给这个顺序表起个名字,接下来给这个结构体定义方法

//初始化线性表
void InitList(SqList &L){
	/*动态分配内存的初始化*/
	L.data = (Elemtype*)malloc(MaxSize * sizeof(Elemtype));  //为顺序表分配空间
	L.length = 0;                                            //初始化长度为0
}

//求表长函数
int Length(SqList &L){
	return L.length;
}

//求某个数据元素值
bool GetElem(SqList &L, int i, Elemtype &e) {
	if (i < 1 || i > L.length)
		return false;         //参数i错误时,返回false
	e = L.data[i - 1];      //取元素值
	return true;
}

//输出线性表
void DispList(SqList &L) {
	if (L.length == 0)
		printf("线性表为空");
	//扫描顺序表,输出各元素
	for (int i = 0; i < L.length; i++) {
		printf("%s   %s   %s     %d", L.data[i].name, L.data[i].tel, L.data[i].id, L.data[i].grade);
		printf("\n");
	}
	printf("\n");
}

//插入数据元素
bool ListInsert(SqList &L, int i, Elemtype e) {
	/*在顺序表L的第i个位置上插入新元素e*/
	int j;
	//参数i不正确时,返回false
	if (i < 1 || i > L.length + 1 || L.length == MaxSize)
		return false;
	i--;                //将顺序表逻辑序号转化为物理序号
	//参数i正确时,将data[i]及后面的元素后移一个位置
	for (j = L.length; j > i; j--) {
		L.data[j] = L.data[j - 1];
	}
	L.data[i] = e;      //插入元素e
	L.length++;         //顺序表长度加1
	return true;
	/*平均时间复杂度为O(n)*/
}

//删除数据元素
bool ListDelate (SqList &L, int i, Elemtype &e) {
	/*删除顺序表中的第i个元素,其值为e*/
	int j;
	if (i < 1 || i > L.length)
		return false;
	i--;              //将顺序表逻辑序号转化为物理序号
	e = L.data[i];
	//参数正确时,将data[i]之后的元素前移一个位置
	for (j = i; j < L.length - 1; j++)
		L.data[j] = L.data[j + 1];
	L.length--;     //顺序表的长度减1
	return true;
	/*平均时间复杂度为O(n)*/
}

//元素查找
int LocateElem(SqList &L, Elemtype e) {
	/*顺序查找第一个值域与e相等的元素逻辑序号(根据e找i)*/
	int i = 0;
	//while循环查找e,这里的依据是姓名
	while (i < L.length && strcmp(L.data[i].name, e.name) != 0)
		i++;
	if (i >= L.length)
		return 0;                      //未找到返回0
	else
		printf("%s    %s    %s     %d", L.data[i].name, L.data[i].tel, L.data[i].id, L.data[i].grade);
	return i + 1;                 //找到后返回其逻辑序号
	/*时间复杂度为O(n)*/
}




3.说明

由于只是算法练习,所以不写完整代码,博主已用线性表完成相关完整项目,可以点击这里查看

二.2010算法真题

1.题目

设将n (n> 1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(Xo, X,Xn- 1)变换为(Xp, Xp+1,……,Xn-1,X0,X1……,Xp-1).要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。

2.分析

可将问题视为把数组ab转换成数组ba (a代表数组的前p个元素,b代表数组中余下的n-p个元素,先将a逆置得到a -1b,再将a -1b逆置得到(a -1b-1),最后将整个a 'b I逆置得到(a -1b-1)-1=ba。

此算法原理来源于考研线性代数矩阵的转换公式,(a -1b-1)-1=ba。以abcdefgh为例:

  • Reverse (0,p-1)得到cbade fgh;
  • Reverse(p,n-1)得到cbahgfed;
  • Reverse(0,n-1)得到de fghabc;

3.算法代码

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

4.说明

最简单的算法题了,必须要会。

考研算法题,不一定看到要时间复杂度和空间复杂度最优就不会,按照平时的练习,能解决问题就行,其余都对只会扣1到2分,哪怕算法不是最优。

所以,如果你想不到这种算法,可以提前申请n个位置,然后把b整体搬迁,能解决问题就行。

三.2011算法真题

1.题目

一个长度为L (L≥1)的升序序列s,处在第[L/2]个位置的数称为s的中位数。例如,若序列Si=(11,13, 15, 17,19),则S;的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2, 4,6,8, 20),则S和S2的中.位数是11。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。

2.分析

算法的基本设计思想如下:
分别求两个升序序列A、B的中位数,设为a和b,求序列A、B的中位数过程如下:
①若a=b,则a或b即为所求中位数,算法结束。
②若a<b,则舍弃序列A中较小的一半,同时舍弃序列B中较大的一半,要求两次舍弃的长度相等。
③若a>b,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,要求两次舍弃的长度相等。
在保留的两个升序序列中,重复过程①、②、③,直到两个序列中均只含.一个元素时为止,较小者即为所求的中位数。

3.算法代码

int M_Search(int A[], int B[], int n) {
	int s1 = 0, d1 = n - 1, m1, s2 = 0, d2 = n - 1, m2;
	//分别表示序列A和B的首位数、末位数和中位数
	while (s1 != d1 || s2 != d2) {
		m1 = (s1 + d1) / 2;
		m2 = (s2 + d2) / 2;
		if (A[m1] == B[m2])
			return A[m1];			//满足条件①
		if (A[m1] < B[m2]) {			//满足条件②
			if ((s1 + d1) % 2 == 0) { //若元素 个数为奇数
				s1 = m1 ;			//舍弃A中间点以前
				d2 = m2;
			}//舍弃B中间点以后
			else {                 //元素个数为偶数
				s1 = m1 + 1 ;
				//舍弃A中间点及中
				d2 = m2;
				// 舍弃B中间点以后
			}
		} else {
			//满足条件③
			if ((s2 + d2) / 2 == 0) { //若元素 个数为奇数
				d1 = m1;
				//舍弃A中间点以后
				s2 = m2;
				//舍弃B中间点以前
			} else {
				// 元素个数为偶数
				d1 = m1;
				//舍弃A中间点以后
				s2 = m2 + 1;
				//舍弃B中间点及中
			}
			return A[s1] < B[s2] ? A[s1] : B[s2] ;
		}
	}
}

4.补充

答案确实是最标准的算法,但是我们很难想到,最简单想到的就是使用归并排序后再求中位数,考试也可以这么干.

四.2013算法真题

1.题目

[2013统考真题]已知一个整数序列A=(a,a1,.,an-1),其中0≤a;<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。要求:

  • 1)给出算法的基本设计思想。
  • 2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
  • 3)说明你所设计算法的时间复杂度和空间复杂度。

2.思路

算法的基本设计思想:算法的策略是从前向后扫描数组元素,标记出一个可能成为主元素的元素Num。然后重新计数,确认Num是否是主元素。
算法可分为以下两步:

  • ①选取候选的主元素。依次扫描所给数组中的每个整数,将第一个遇到的整数Num保存到c中,记录Num的出现次数为1;若遇到的下一个整数仍等于Num,则计数加1,否则计数减1;当计数减到0时,将遇到的下一个整数保存到c中,计数重新记为1,开始新一轮计数,即从当前位置开始重复上述过程,直到扫描完全部数组元素。
  • ②判断c中元素是否是真正的主元素。再次扫描该数组,统计c中元素出现的次数,若大于n/2,则为主元素;否则,序列中不存在主元素。

3.算法代码

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++;
	//对A中的候选主元素计数
		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 ;
			// 不存在主元素
		}
}

4.补充

我们想不出来这种算法,另一种思路,由于它给定了每个值的范围[0,n]之间,我们可以遍历整个数组等到每个元素的计数器组成新的数组,再遍历这个数组是否有>n/2的存在。

五.2018算法真题

1.题目

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

2.思路

要求在时间上尽可能高效,因此采用空间换时间的办法。分配一个用于标记的数组B[n],用来记录A中是否出现了1~n 中的正整数,B[0]对应正整数1,B[n-1]对应正整数n,初始化B中全部为0。由于A中含有n个整数,因此可能返回的值是1~n+1,当A中n个数恰好为1~n时返回n+1。当数组A中出现了大于或等于0或大于n的值时,会导致1~n中出现空余位置,返回结果必然在1~n中,因此对于A中出现了大于或等于0或大于n的值,可以不采取任何操作。

3.算法代码

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)
			//若A[i]的值介于1~n,则标记数组B
			B[A[i] - 1] = 1;
	for (i = 0; i < n; i++)
		//扫描数组B,找到目标值
		if (B[i] == 0) break;
	return i + 1;
}

4.补充

上一道题的次优解法思路,典型的空间换时间.

六.2020算法真题

1.题目

[2020统考真题]定义三元组(a, b,c) (a, b, c均为整数)的距离D= |a-b|+ |b-c|+|c-a|。给定3个非空整数集合S、S2和S3,按升序分别存储在3个数组中。请设计一个尽可能高效的算法,计算并输出所有可能的三元组(a, b,c)(a∈S,b∈S2, c∈S;)中的最小距离。例如Si={-1,0,9}, S2={-25,-10, 10,11},S3= {2,9, 17,30,41},则最小距离为2,相应的三元组为(9, 10,9)。要求:

  • 1)给出算法的基本设计思想。
  • 2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
  • 3)说明你所设计算法的时间复杂度和空间复杂度。

2.思路

由D的表达式可知,事实上决定D大小的关键是a和c之间的距离,于是问题就可以简化为每次固定c找一个a,使得L3=|c- a|最小。
1)算法的基本设计思想

  • ①使用Dmin记录所有已处理的三元组的最小距离,初值为一个足够大的整数。
  • ②集合S、S2和S3 分别保存在数组A、B、C中。数组的下标变量i=j=k=0,当i<|S|j<|S2|且k< |Ss|时(|S|表示集合S中的元素个数),循环执行下面的a) ~c)。
    • a)计算(A[i], B[], C[k])的距离D; (计算 D)
    • b)若D<Dmin,则Dmin=D; (更新D)
    • c)将A[]、B[小]、C[k]中的最小值的下标+1; (对照分析:最小值为a,最大值为c,这里
      C不变而更新a,试图寻找更小的距离D)
  • ③输出Dmin, 结束。

3.算法代码

wPDG.jpg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGLM的模型架构

ChatGLM的部署微调等&#xff0c;很多资料&#xff0c;不再赘述。 P-tuning V2 以P-Turing V2为例&#xff0c;介绍ChatGLM的网络结构。P-tuning V2方法训练时冻结模型的全部参数&#xff0c;只激活prefix_encoder的参数。 1、prefix encoder 初始化pre_len&#xff0c;代表…

Apple pencil平替哪款好?平价电容笔测评

现今&#xff0c;使用电容笔的人越来越多&#xff0c;各大品牌厂商对电容笔各种性能的设计也愈发用心。那么&#xff0c;电容笔哪个品牌好用呢&#xff1f;下面&#xff0c;我来给大家推荐几款质量好的Apple pencil平替&#xff0c;需要的小伙伴可以当个参考。 一、如何挑选到…

Vue3+TS+Vite开发组件库并发布到npm

Vue2开发插件并发布到npm 使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub 目标&#xff1a;创建 vue-amazing-ui 组件库 &#xff0c;并发布到npm 该组件库已发布到 npm&#xff0c;直接安装即可使用&#xff1a; pnpm i vue-amazing-ui #or yarn add vue-a…

(十一)K8S可视化工具Rancher学习、安装

1.Rancher背景概述 在过去几年中&#xff0c;容器技术如 Docker 和容器编排引擎如 Kubernetes 受到了广泛关注和采用&#xff0c;它们为应用程序的部署、可扩展性和管理带来了革命性的变化。 然而&#xff0c;随着容器技术的快速发展&#xff0c;容器集群的管理和操作变得越来…

【笔试强训选择题】Day21.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、…

hadoop搭建、mysql、hive部署

写在前面&#xff1a; 本篇文章基于linux系统Centos7环境下进行搭建、操作 仅作为学习参考借鉴&#xff0c;欢迎大家交流学习&#xff01;一、 HDFS安装搭建 1.1 关闭虚拟机防火墙 在之后的学习、操作中&#xff0c;经常会遇到在宿主机中通过程序去访问虚拟机中的相关软件&am…

再获肯定!Coremail入选2023网络空间安全大会优秀案例!

6月2日-3日&#xff0c;在中国电子学会主办的“2023网络空间安全大会”上&#xff0c;由广东盈世计算机科技有限公司申报的“Coremail邮件安全解决方案”获评2023网络空间安全大会优秀案例&#xff0c;再次获得行业权威认可&#xff01; 本次大会由中国电子学会主办&#xff0c…

hudi系列-append写过程

前言 Append模式每次都生成新的parquet文件,不涉及数据修改、去重。cow+insert一直是append模式,mor+insert在0.13.1后也统一走append写流程(HUDI-6045) 在0.13.1之前,mor+insert存在着写parquet和写log两种情况: 写parquet:compaction.schedule.enabled = false & …

Loadrunner和JMeter、Locust三款性能测试工具全面对比

随着软件技术的发展&#xff0c;软件应用越来越普遍&#xff0c;不仅仅是互联网大厂的应用需要进行性能测试了&#xff0c;就连一些中小型的互联网应用也越来越需要对软件项目进行性能测试了。所以本文就将通过Loadrunner、JMeter和Locust三款性能测试工具从以下几个方面进行介…

QML学习二:Doxygen为qml工程生成代码文档

效果如下: 设置后能够支持.js和.qml文档。 QML学习二:Doxygen为工程生成注释文档 前言一、安装doxyqml二、Doxygen设置1.文档目录设置2.文档目录设置三、添加注释总结前言 好的代码必须配一个好的文档说明,方便以后维护以及学习。 前提条件: 1.安装好了Doxygen代码生成工…

快速搭建,降低成本!了解低代码平台适用的五大场景

对于希望简化应用程序开发流程的公司来说&#xff0c;低代码平台已经成为一种有效的解决方案。这些平台使创建和部署应用程序成为可能&#xff0c;而不需要广泛的编码技能或知识&#xff0c;从而使过程更快、更高效、更具成本效益。但是&#xff0c;低代码平台适用于哪些场景呢…

《操作系统》by李治军 | 实验6 - 信号量的实现和应用

目录 一、实验目的 二、实验内容 &#xff08;一&#xff09;用信号量解决生产者—消费者问题 &#xff08;二&#xff09;实现信号量&#xff0c;用生产者—消费者程序检验 三、实验准备 1、信号量 2、多进程共享文件 3、终端也是临界资源 4、原子操作、睡眠和唤醒 …

接口测试 —— 接口测试定义

1、接口测试概念 &#xff08;重点&#xff09; 接口测试是测试系统组件间接口的一种测试&#xff0c;它界于单元测试与系统测试中间。 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是要检查数据的交换&#xff0c;传递和控制管理过…

pinia 持久化插件pinia-plugin-persistedstate 安装、使用(图文详解)

序&#xff1a; 1、博主vue3、ts 5.x、pinia 2.1.3版本&#xff0c; 2、所以如果试了不行的你看看是不是自己版本和博主的对不上 3、其实就是省略掉localStorage 这一步&#xff0c;会自己写的小伙伴自己写个也是蛮快的 4、放个中文文档》Home | pinia-plugin-persistedstate 5…

【Verilog】汉明码

文章目录 汉明码定义校验位个数编码规则一个例子编码解码 C实现功能编写测试结果 Verilog实现.v功能代码testbench波形 汉明码 定义 在传输的信息流中插入验证码&#xff0c;侦测单一比特错误只能发现和修正一位错误&#xff0c;对于两位或两位以上的错误无法发现与修正 校验…

iSCSI共享存储搭建

1.简介 iSCSI&#xff1a;Internet Small Computer System Interface&#xff0c;Internet小型计算机系统接口&#xff0c;又称为IP-SAN&#xff0c;是一种基于因特网及SCSI-3协议下的存储技术。 2.iSCSI的作用 基于客户端和服务端架构的虚拟磁盘技术&#xff0c;服务端提供…

如何让url在新页面打开路由页面,并脱离vue-admin-template的壳,即不包裹在侧边栏和顶栏中

文章目录 一、打开的页面不包裹在侧边栏和顶栏中二、新窗口打开&#xff08;_blank&#xff09;三、最终效果 一、打开的页面不包裹在侧边栏和顶栏中 在使用vue-admin-template新建的页面中&#xff0c;打开的页面都是在框架内的内容区。 但假如我需要在左侧点击一个链接&…

面试题丨android面试问题合集

1、项目里静态分析和基于xposed动态工具介绍一下&#xff0c;如果不使用xposed&#xff0c;怎么实现动态分析工具&#xff1f; 静态分析工具是指在不运行程序的情况下&#xff0c;通过对程序文件进行源代码分析&#xff0c;从而对程序的安全性、可靠性、性能等进行分析的工具。…

HOOPS技术如何助力企业数字化转型?

近年来&#xff0c;随着科技的迅速发展&#xff0c;数字技术的应用已经深入到各个行业和领域。云计算、人工智能、物联网、大数据分析等技术的成熟和普及&#xff0c;为企业提供了丰富的数字化工具和解决方案。企业意识到利用这些技术可以提高效率、降低成本、创新业务模式&…

学习中心上新丨Python教程-Django框架快速入门到实战

腾讯云千锋教育强强联手&#xff0c;一同研发重磅推出全新课程《千锋图片云存储》Python 教程-Django 框架从入门到实战-基于腾讯云 COS Django框架实战教程发布 腾讯云开发者社区“学习中心”直达&#xff1a; 腾讯云开发者社区-腾讯云 扫码加入“腾讯云开发者社区学习中心交…