类C语言实现顺序表中的基本操作

自己在学习数据结构中(DS)写得程序,和大家一起分享,可能存在不足和缺漏的地方,感谢大家的指正和理解。

首先是一些变量的声明(typedef),然后是定义顺序表的类型(里面含有数组(存储数据元素)和表长),再接下来是对线性表SqList进行的增删改查,最后是自己的测试样例(针对于插入和删除)。

代码展示:

#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2typedef int Status;
typedef int ElemType;#include <iostream>
using namespace std;
typedef struct
{ElemType *elem;int length;
}SqList;		//定义顺序表的类型//顺序表的初始化
Status InitList(SqList &L)
{//构造一个空的顺序表LL.elem = new ElemType[MAXSIZE];		//为顺序表分配一个大小为MAXSIZE的数组空间if(!L.elem) exit (OVERFLOW);		//存储分配失败L.length=0;							//空表的长度为0return OK; 
}//销毁线性表 
void DestroyList(SqList &L)
{if(!L.elem) delete L.elem;			//释放存储空间 
}//清空线性表L
void ClearList(SqList &L)
{L.length = 0;						//将线性表的长度置为0 
} //求线性表的长度
int GetLength(SqList L)
{return (L.length);
}//判断线性表是否为空
int IsEmpty(SqList L)
{if(L.length == 0)	return 1;else return 0;
} //顺序表的取值
Status GetElem(SqList L, int i, ElemType &e)      
{if(i<1||i>L.length) return ERROR;	//判断i值是否合理,若不合理,返回ERRORe = L.elem[i-1];					//elem[i-1]单元存储第i个元素return OK; 						
}//顺序表的查找 
int LocateElem(SqList L, ElemType e)
{//在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)for(int i=0; i<L.length; i++){if(L.elem[i]==e)	return i+1;		//查找成功,返回序号return 0;							//查找失败,返回0 } 
} //顺序表的插入
Status ListInsert(SqList &L, int pos, ElemType e)
{	//1.判断插入位置是否合法 if(pos<1||pos>L.length+1)	return ERROR;//2.判断当前存储空间是否满 if(L.length==MAXSIZE)	return ERROR;//3.将数组中最后一个至第pos个位置的元素依次向后移动,空出第pos个位置//(pos=n+1时无需移动) //4.将要插入的新元素e 放入到第pos个位置//5.表长加1 for(int i=L.length-1; i>=pos-1;i--) L.elem[i+1]=L.elem[i];				//插入位置及之后的元素后移 L.elem[pos-1] = e;			//将新元素e放到第pos个位置 L.length++;					//表长加1 return OK;
}//顺序表的删除
Status	ListDelete(SqList &L, int i)
{//在顺序表L中删除第i个元素,i的合法取值范围:1<=i<=L.lengthif((i<1)||(i>L.length))		return ERROR;	//i值不合法for(int j=i; j<=L.length-1; j++)L.elem[j-1]=L.elem[j];		//被删除元素之后的的元素前移L.length--;					//表长减1return OK; 
} int main()
{SqList L;//线性表初始化(空的线性表)InitList(L);//插入测试样例 ListInsert(L,1,1);ListInsert(L,2,2);ListInsert(L,3,3);ListInsert(L,4,4);ListInsert(L,5,5);//看能否插入成功//输出这个线性表ListInsert(L,1,100);//上述的运行结果:100 1 2 3 4 5 //测试删除元素:ListDelete(L,4);	//100 1 2 4 5for(int i=0; i<L.length; i++){cout<<L.elem[i]<<" ";}
} 

操作的说明:初始化,销毁,清空,求表长,判空,取值代码比较简短,理解起来容易一点,其中取值便是利用了数组的随机存取性质,因为你给定一个下表,数组便能对应到其元素,因此算法时间复杂度为O(1)。

接下来我对查找,插入,删除进行相应的算法描述和对应的时间复杂度分析。

时间复杂度分析时引入平均查找长度的概念(ASL),它是在查找时,为了确定元素在顺序表中的位置,需要和给定值进行比较的数据元素个数的期望值

ASL=\sum piCi

其中pi是查找第i个元素的概率,Ci是找到表中其关键字与给定值相等的第i个记录时,和给定值已经比较的关键字个数。

顺序表的查找:

(1)从第一个元素起,依次和e值比较,若找到与e相等的元素L.elem[i],则查找成功,返回该元素的序号i+1。

(2)若查找整个顺序表都没有找到,则查找失败,返回0。

算法分析:从顺序表的查找过程可见,Ci取决于所查元素在表中的位置。例如:查找表中第一个记录时,只需比较一次;而查找表中最后一个记录时,则需比较n次。一般情况下Ci=i。

假设每个元素的查找概率相等,即pi=1/n

则ASL=1/n\sumi=(n+1)/2

由此可见,顺序表按值查找算法的平均时间复杂度为O(n)。

顺序表的插入:

(1)判断插入位置是否合法(pos的合法范围是1<=i<=n+1),若不合法则返回ERROR。

(2)判断顺序表的存储空间是否已满,若满则返回ERROR。

(3)将第n个至第pos个位置的元素依次向后移动一个位置,空出第pos个位置(pos=n+1时无需移动)。

(4)将要插入的新元素放入第i个位置。

(5)表长加1。

补充说明:上述算法没有处理动态的扩容,因此当表达到预设的最大空间时,则不能再插入元素。

算法分析:当在顺序表中某个位置插入一个数据元素时,其时间主要消耗在移动元素上,而移动元素的个数取决于插入元素发位置。

我们不妨设移动的元素的次数为x,给定插入的位置为i,长度为n的线性表总共可以插入的元素位置有n+1个。我们发现它们之间的关系是n+1=x+i。

当插入的位置n+1,我们对原数组不需要进行任何操作,移动次数x=0。

插入的位置为n时,我们需要将初始最后一个元素移动,腾出那个空间放e,前面的数据元素保持不变,移动次数x=1。

当插入的位置为1时,我们需要将所有的数据元素(n)个都要向后移动,腾出的第一个位置放新元素e。移动的次数x=n。

可能有人会问为什么第一个位置的前面不可以插入元素?

在大多数编程语言中,数组是一种线性数据结构,它允许你存储一系列的元素,并通过索引来访问这些元素。数组的一个重要特性是它有固定的长度,一旦创建,其大小通常不能改变。这意味着你不能在数组的“第一个位置前面”插入元素,因为数组的第一个位置(索引为0的位置)已经是数组的开始。而我们可以在结尾插入元素。

为什么在对数组进行插入操作时,需要将数据元素往后挪动一个位置?

在对数组进行插入操作时,需要将数据元素往后挪动一个位置,这主要是因为数组是一种固定长度的数据结构,其元素在内存中是连续存储的。当你想在数组的某个特定位置插入一个新元素时,必须确保新元素能够找到合适的空间来存放,同时不覆盖或丢失原有元素的数据。

不失一般性,可以假定在线性表中的任何位置(n+1)插入元素都是等概率的,即Pi=1/n+1

根据ASL的公式:Eins =1/n+1\sum(n-1+1)=n/2

由此可见,顺序表插入算法的平均时间复杂度为O(n)。

顺序表的删除:

算法描述:

(1)判断删除位置i是否合法(1<=i<=n+1),若不合法返回ERROR。

(2)将第i+1个至第n个元素依次向前移动一个位置(i=n时无需移动)。

(3)表长减1。

算法分析:

当在顺序表中某个位置删除一个数据元素时,其时间主要消耗在移动元素上,而移动元素的个数取决于删除元素的位置。

不失一般性,可以假定在线性表中的任何位置上删除元素都是等概率的,即pi=1/n。

我们可以发现移动次数x=n-i。

当删除的位置i=n,移动次数x=0

i=n-1,x=1。

i=1,x=n-1(除第一元素外,剩下的n-1个元素往前移动一个位置)。

Edel=1/n\sum(n-i)=(n-1)/2。

由此可见,顺序表删除算法的平均时间复杂度为O(n)。

顺序表可以随机存取任一元素,其存储位置可以用一个简单、直观的公式来表示。然而,从另一方面来看,这个特点也造成了这种存储结构的缺点:在做插入删除操作时,需要移动大量元素。另外由于数组有长度相对固定性的静态特性,当表中数据元素个数较多且变化较大时,操作过程相对复杂,必然导致存储空间的浪费。所有这些问题,都可以通过线性表的另一种表示方法——链式存储结构来解决。

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

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

相关文章

重读 Java 设计模式: 深入探讨工厂模式,创建对象的灵活性与可维护性

引言 今天我们来继续学习创建型设计模式中的工厂模式。在软件开发中&#xff0c;工厂模式是一种常见的设计模式&#xff0c;旨在提供一种灵活、可扩展的方式来创建对象实例。工厂模式通常分为简单工厂模式和抽象工厂模式两种主要形式&#xff0c;它们在不同情境下各具优势&…

Jenkins 面试题及答案整理,最新面试题

Jenkins中如何实现持续集成与持续部署&#xff1f; Jenkins通过自动化构建、测试和部署应用程序来实现持续集成与持续部署&#xff08;CI/CD&#xff09;。这个过程包括以下步骤&#xff1a; 1、源代码管理&#xff1a; Jenkins支持与多种版本控制系统集成&#xff0c;如Git、…

路由器端口转发远程桌面控制:一电脑连接不同局域网的另一电脑

一、引言 路由器端口转发&#xff1a;指在路由器上设置一定的规则&#xff0c;将外部的数据包转发到内部指定的设备或应用程序。这通常需要对路由器进行一些配置&#xff0c;以允许外部网络访问内部网络中的特定服务和设备。端口转发功能可以实现多种应用场景&#xff0c;例如远…

考研C语言复习进阶(6)

目录 1. 程序的翻译环境和执行环境 2. 详解编译链接 2.1 翻译环境 ​编辑​编辑 2.2 编译本身也分为几个阶段&#xff1a; 2.3 运行环境 3. 预处理详解 3.1 预定义符号 3.2 #define 3.2.1 #define 定义标识符 3.2.2 #define 定义宏 2.2.3 #define 替换规则 3.2.4…

Ubuntu 如何安装 Beyond Compare?

Ubuntu20.04安装Beyond Compare 4.3.7 一、官网下载方式一&#xff1a;方法二&#xff1a;使用 .deb 包安装 二、安装相关依赖和bcompare三、破解常见错误解决方法 ) 文件比较工具Beyond Compare是一套由Scooter Software推出的文件比较工具。主要用途是对比两个文件夹或者文件…

【大模型系列】问答理解定位(Qwen-VL/Llama2/GPT)

文章目录 1 Qwen-VL(2023, Alibaba)1.1 网络结构1.2 模型训练 2 Llama2(2023, Meta)2.1 网络结构2.1.1 MHA/GQA/MQA2.1.2 RoPE(Rotary Position Embedding, 旋转式位置编码)2.1.3 RMSNorm 2.2 推理2.2.1 集束搜索(beam search)2.2.2 RoPE外推 3 GPT系列(OpenAI) 1 Qwen-VL(2023…

贪心算法(两个实例)

例一&#xff1a;调度问题 问题&#xff1a;由n项任务&#xff0c;每项任务的加工时间已知&#xff0c;从零时刻开始陆续加入一台机器上去加工&#xff0c;每个任务完成的时间是从0时刻到任务加工截至的时间。 求总完成时间&#xff08;所有任务完成时间最短计划方案&#xf…

vue3新功能-Teleport

1.teleport 在组件内的任何位置渲染内容 将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。 例:将组件dialog添加到body下面 <teleport to"body"> <el- dialog --> </teleport> 2.fragments 多个根元素外层不需要…

解决Linux中Eclipse启动时找不到Java环境的问题

按照报错的意思是没有在/usr/local/eclipse/jre/bin/java下找到java环境&#xff0c;我检查了一下eclipse的目录结构发现在/usr/local/eclipse没有jre/bin/java&#xff0c;我的想法是自己建对应文件夹然后软连接到我的java环境 cd /usr/local/eclipse sudo mkdir jre cd jre s…

CSS其他属性

文章目录 1. vertical-align1.1. 概念1.2. 常用值1.3. 作用1.4. 出现的情况一1.4.1. 原因1.4.2. 解决方案 1.5. 出现情况二1.5.1. 解决方案一1.5.2. 解决方案二1.5.3. 解决方案三 1.6. 出现情况三1.6.1. 原因1.6.2. 解决方案 2. 溢出效果2.1. 作用2.2. 属性名 3. 隐藏效果3.1. …

软考78-上午题-【面向对象技术3-设计模式】-结构型设计模式01

一、适配器模式 1-1、意图 个类的接口转换成客户希望的另外一个接口。 Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 1-2、结构 适配器模式分为&#xff1a; 1、适配器类模式&#xff1b; 2、适配器对象模式 类适配器使用多重继承对一个接口与另…

Spring Cloud Alibaba微服务从入门到进阶(五)(负载均衡-Ribbon)

负载均衡有两种形式&#xff0c;服务器端负载均衡/客户端负载均衡 1、服务器端负载均衡 因为Nginx是部署在服务器端的&#xff0c;所以用Nginx实现的负载均衡被称为服务器端负载均衡 2、客户端负载均衡 手写一个客户端侧负载均衡器 使用Ribbon实现负载均衡 Ribbon是Netflix…

GitLab 面试题及答案整理,最新面试题

GitLab 在持续集成/持续部署(CI/CD)中的角色是什么&#xff1f; GitLab 在持续集成/持续部署(CI/CD)中扮演的角色非常关键&#xff0c;主要体现在以下几个方面&#xff1a; 1、自动化构建和测试&#xff1a; GitLab 可以自动化执行代码的构建和测试过程&#xff0c;确保代码提…

[自研开源] MyData 数据集成之数据过滤 v0.7.2

开源地址&#xff1a;gitee | github 详细介绍&#xff1a;MyData 基于 Web API 的数据集成平台 部署文档&#xff1a;用 Docker 部署 MyData 使用手册&#xff1a;MyData 使用手册 试用体验&#xff1a;https://demo.mydata.work 交流Q群&#xff1a;430089673 概述 本篇基于…

生态系统服务——食物生产功能分布数据

食物生产数据为县生态系统提供的粮食、水产品、肉类、林果产品等食物产量&#xff0c;统一转换为能量。 地理遥感生态网提供的生态系统服务——食物生产功能分布数据&#xff0c;计算中以县为单元对各种粮食、肉、蛋、奶、水果产量进行核算。其中&#xff0c;食物供给功…

实战:django项目环境搭建(pycharm,virtualBox)

django项目环境搭建 一.创建虚拟环境二.创建PyCharm远程连接 一.创建虚拟环境 需要用到的软件&#xff1a;PyCharm&#xff0c;VirtualBox虚拟机。 1.打开虚拟机终端&#xff0c;创建新的虚拟环境 Book。 2.在虚拟环境中创建新的文件夹 library&#xff0c;cd命令进入该文件…

《操作系统导论》第二章读书笔记

《操作系统导论》第二章读书笔记 —— 杭州 2024-03-17 夜 文章目录 《操作系统导论》第二章读书笔记1.操作系统&#xff08;Operating System&#xff0c;OS&#xff09;2.虚拟化CPU3.虚拟化内存4.并发5.持久性6.设计目标和简单历史 1.操作系统&#xff08;Operating System&a…

C#操作MySQL从入门到精通(4)——连接MySQL数据库

前言 我们创建好数据库、建立好数据库的表以后&#xff0c;我们就需要访问数据库了&#xff0c;比如将数据插入数据库的某张表中等一系列操作&#xff0c;在进行这些操作之前我们需要连接上数据库&#xff0c;本文就是详细讲解如何连接MySQL数据库的。 1、使用Navicat Premiu…

JavaWeb--HTML

一&#xff1a;HTML简介 *HTML是一门语言&#xff0c;所有的网页都是用HTML这门语言编写出来的&#xff1b; *HTML&#xff1a;超文本标记语言&#xff1b; 超文本&#xff1a;超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还能定义图片&#xff…

给定参数c和长度为n的递增数组a(ai <= c), 对于0<=x<=y<=c, 求(x,y)的对数,满足x+y不是数组a中的元素且y-x不是a中元素

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, …