线性表的顺序存储结构(数组插入,删除)——c语言描述

2023-11-16

1. 线性表的顺序存储结构

1.2 线性表的存储结构的表示**

​ 顺序存储结构类似数组存储结构。

代码:

**分析:**Len表示线性表的长度

#define SUCCESS            1
#define ERROR          0
#define MAXSIZE            10

typedef int ElemType;
typedef int LIST_STATUS;

typedef struct SQ_LIST_ {
​     ElemType Data[MAXSIZE];int Len;
}SQ_LIST;

SQ_LIST L;

1.2 线性表的操作****OperatorList()**

​ 对应线性表的抽象数据类型,有以下的操作:创建线性表并赋值,打印线性表的内容,清空线性表,返回线性表对应序号的值,在线性表查相应的值,增加线性表的元素,删除线性表的元素。

LIST_STATUS OperatorList() {
	LIST_STATUS Status;
	int GetIndex = 2;
	int GetE;
	int LoElm = 3;
	int InsertIndex = 2;
	int InsertElm = 15;
	int DeleteIndex = 2;	

	CreatList(&L);
	PrintList(L);
	
	/*
	ClearList(&L);
	PrintList(L);
	*/

	/*
	GetElem(&L, GetIndex, &GetE);
	printf("The GetIndex = %d, GetE = %d\n", GetIndex, GetE);
	*/

	/*
	Status = LocateElem(L, LoElm);
	printf("Status = %d\n", Status);
	*/

	/*
	Status = InsertElem03(&L, InsertIndex, InsertElm);
	if (ERROR == Status) {
		printf("InsertElem faild!\n");		
	}
	*/

	Status = DeleteElem01(&L, DeleteIndex);
	if (ERROR == Status) {
		printf("DeleteElem01 faild!\n");
	}
	PrintList(L);
	return Status;
}

1.3 打印线性表****PrintList**

​ 打印线性表的各个元素和长度。

代码:

LIST_STATUS PrintList(const SQ_LIST L) {int i = 0;printf("Print List:\n");for (i = 0; i < L.Len; ++i) {printf("L.Data[%d] = %d\n", i, L.Data[i]);}printf("L.Len= %d\n", i, L.Len);return SUCCESS;
}

1.4 创建线性表**

​ 创建一个线性表,里面存储三个值。

代码:

LIST_STATUS CreatList(SQ_LIST *const L) {
​     L->Data[0] = 1;
​     L->Data[1] = 2;
​     L->Data[2] = 3;
​     L->Len = 3;return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

1.5 清零线性表****ClearList**

​ 将线性表里面的成员清零。

代码:

LIST_STATUS ClearList(SQ_LIST * const L) {printf("Clear list:\n");memset(L, 0, sizeof(SQ_LIST));return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

Clear list:

Print List:

L->Len= 0

1.6 获取线性表指定位置的值****GetElem**

​ 返回第二个元素的值。

**分析:**先判断线性表的长度是否为0和输入的位置是否合法,再将位置对应的值返回。

代码:

LIST_STATUS GetElem(const SQ_LIST *const L, const int GetIndex, int * const GetE) {if ( 0==L->Len || GetIndex<1 || GetIndex>L->Len ) {return ERROR;}*GetE = L->Data[GetIndex -1];return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

The GetIndex = 2, GetE = 2

1.7 查找元素****LocateElem**

**问题:**查找给定元素,查找到返回成功,否则失败

代码:

LIST_STATUS LocateElem(const SQ_LIST L, const int LoElm) {int Index = 0;printf("\nLocateElem:\n");if (0 == L.Len) {return ERROR;}for (Index = 0; Index < L.Len; ++Index) {if (LoElm == L.Data[Index]) {return SUCCESS;}}if (Index == L.Len) {return SUCCESS;}
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

LocateElem:

Status = 1

1.8 插入元素**

**问题:**在线性表的第InsetIndex个位置中插入一个元素Ele。如a[0], a[1], a[2], a[3], 要在a[0]后面插入一个元素Elm。比如a[0], a[1], a[2], a[3], 要在a[0]后面插入一个元素Elm。

分析:

①判断是否长度和输入的参数是否合法:首先线性表是否已满(长度的是否为最大值);判断插入的位置是否合法(不能比1小,不能比线性表长度+1的位置还大);

② 先后移数组元素:当插入表头位置或者表中间位置时,先将线性表的元素后移一位,再将元素插入指定位置,增加线性表的长度;当插入线尾时,不用移动线性表,直接往后面添加,并增加线性表的长度。用循环方法,把

即:a[2] = a[1], a[3] =a[2], a[4] = a[3]。

③插入元素并增加线性表的长度。即a[1] = Elm, Len++

线性表元素往后移动的两种算法:

从前往后遍历 ——从下标1遍历到下标3

**双指针方法。a[0], a[1], a[2], a[3]。**一个指针pre向前一个的元素,一个指针cur指向目前的元素。实现循环体的时候,需要引入中间变量Temp将后一个元素先存起来。

分析:

初始化: Pre = a[1], Cur = a[2]

循环体:Temp = a[2],Cur = Pre

移动指针:Pre = Temp,Cur = a[3]

使用循环:for(i = 0; i < n; ++i), Cur可以用a[i]代替,初始化中Cur可以与循环合在一起,Pre可以用a[i-1].

修改后的版本:

//初始化
Pre = a[InsetIndex - 1];
for (i = InsetIndex; i < Len; ++i) {//循环体
​     Temp = a[i];
​     a[i] = Pre;//移动指针
​     Pre = Temp;
}

代码:

LIST_STATUS InsertElem02(SQ_LIST * const L, const int InsertIndex, const int InsertElm) {int Pre;int Temp;int i;printf("\nInsertElem start:\n");if (MAXSIZE == L->Len || InsertIndex < 1 || InsertIndex > L->Len + 1) {printf("Invaild Len or InserInsex!\n");return ERROR;}//Initialize
​     Pre = L->Data[InsertIndex - 1];for (i = InsertIndex; i <= L->Len; ++i) {//Loop
​          Temp = L->Data[i];      
​          L->Data[i] = Pre;//Move Pre
​          Pre = Temp;}
 
​     L->Data[InsertIndex - 1] = InsertElm;
​     L->Len++;printf("InsertElem end:\n");return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

InsertElem start:

InsertElem end:

Print List:

L.Data[0] = 1

L.Data[1] = 15

L.Data[2] = 2

L.Data[3] = 3

L.Len= 4

从后往前遍历 ——从下标4遍历到下标1

**分析:**a[0], a[1], a[2], a[3]。不用使用中间变量存储中间的值,a[4] = a[3], a[3] = a[2], a2[2] = a[1].

代码:

LIST_STATUS InsertElem03(SQ_LIST * const L, const int InsertIndex, const int InsertElm) {int i = 0;printf("\nInsertElem start:\n");if (MAXSIZE == L->Len || InsertIndex < 1 || InsertIndex > L->Len + 1) {printf("\nInvaild Len or InserInsex!\n");return ERROR;}for (i = L->Len; i >= InsertIndex - 1; --i) {
​          L->Data[i] = L->Data[i-1];}

​     L->Data[InsertIndex - 1] = InsertElm;
​     L->Len++;printf("InsertElem end:\n");return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

InsertElem start:

InsertElem end:

Print List:

L.Data[0] = 1

L.Data[1] = 15

L.Data[2] = 2

L.Data[3] = 3

L.Len= 4

1.9 删除元素**

**问题:**在线性表的第InsetIndex个位置中删除一个元素a[InsetIndex]。如a[0], a[1], a[2], a[3], 要删除a[1],比如a[0], a[1], a[2], a[3]。要删除是头或者中间的时候,移动数组。要删除是表尾时,不用移动数组。

**分析:**a[2], a[3]往前移动。长度减一

两种算法:

算法1:从前往后遍历

代码:

LIST_STATUS DeleteElem01(SQ_LIST * const L, const int DeleteIndex) {int i = 0;if (0 == L->Len || DeleteIndex < 1 || DeleteIndex > L->Len) {printf("\nInvaild Len or DeleteIndex!\n");return ERROR;}for (i = DeleteIndex - 1; i < L->Len - 1; ++i) {
​          L->Data[i] = L->Data[i + 1];}
    
​     L->Len--;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

Invaild Len or DeleteIndex!

DeleteElem01 faild!

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

算法2:从后往前遍历

**分析:**双指针法,Cur指向当前的元素,Pre指向之前的元素,Temp将中间变量保存起来

代码:

LIST_STATUS DeleteElem02(SQ_LIST * const L, const int DeleteIndex) {int i = 0;int Pre;int Temp;printf("\nDeleteElem start:\n");if (0 == L->Len || DeleteIndex < 1 || DeleteIndex > L->Len) {printf("\nInvaild Len or DeleteIndex!\n");return ERROR;}

​     Pre = L->Data[L->Len - 1];for (i = L->Len - 2; i >= DeleteIndex - 1; --i) {
​          Temp = L->Data[i];
​          L->Data[i] = Pre;
​          Pre = Temp;}

​     L->Len--;printf("\nDeleteElem end\n");return SUCCESS;
}

结果:

Creat list:

Print List:

L.Data[0] = 1

L.Data[1] = 2

L.Data[2] = 3

L.Len= 3

DeleteElem start:

DeleteElem end

Print List:

L.Data[0] = 1

L.Data[1] = 3

L.Len= 2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线性表的顺序存储结构(数组插入,删除)——c语言描述 的相关文章

随机推荐

  • TensorIR快速入门

    本文翻译自Blitz Course to TensorIR tvm 0 9 dev0 documentation TensorIR是一种用于深度学习程序的特定领域的语言 服务于两个广泛的目的 在各种硬件后端上转换和优化程序的实现 对自动向量
  • linux数据库的测试连接,你会遇到哪些问题?

    linux安装数据库及测试连接 第一步 第二步 第三步 第四步 本文将介绍用阿里云服务器安装两种版本的数据库 及连接时会遇到的问题 一种是5 6 一种是8 0 第一步 安装完成后 测试连接 service mysqld status 第二步
  • 当经历所有大厂的实习面试过后

    学而不思则罔 思而不学则殆 当走完基本所有大厂之后 发现其实每个公司对基础能力的考察都比较注重 只有基础掌握好了 把前端所有的知识能够一连串的理清 那么不管面试题是什么 都可以游刃有余的去回答 这里就是把我所有面试过的问题的一些底层原理阐述
  • 用Docker部署自己的JupyterHub

    话在前头 用 Docker 部署 JupyterLab 感觉是部署 JupyterLab 最方便的方式了 官方提供了很多可选的镜像 也可以自己从 jupyter base notebook 中继续打包 镜像启动命令加上 NotebookAp
  • 使用tf.keras实现 softmax多分类的代码

    softmax多分类 多分类问题的关键在于输出10个概率值 然后使用softmax进行激活 softmax激活函数 能把10个输出变为10个概率分布 然后这10个概率的和为1 1 对数几率回归 解决的是 二分类的问题 对于 多个选项 的问题
  • [云原生专题-42]:K8S - 核心概念 - placeholder-有状态服务

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 placeholder 作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址
  • 讲一点点自动驾驶技术(1)概论

    讲一点点自动驾驶技术 1 概论 作为一个自动驾驶小菜鸟工程师 小Q入门才两三年时间 最近空闲时间比较多 利用这个平台把自己对于无人驾驶技术所看所学的东西在这进行一个整理 一来自己看着方便 二来供大家交流学习 Xiao Xi ps 如果大家觉
  • github 上传和拉取 support for passward authentication was removed...

    参考下面这篇文章 remote Support for password authentication was removed on August 13 2021 IT博客技术分享的博客 CSDN博客 但是记得把repositories和
  • Java教程【01.02】Java引用类型数组和继承的意义

    Java引用类型数组和继承的意义 Java引用类型数组和继承是Java中常用的两个概念 它们在编程中起到重要的作用 在本教程中 我们将讨论Java引用类型数组的使用以及继承的意义 并提供相关的示例 步骤1 创建引用类型数组 Java中的引用
  • AI2.0:十年之后我们还能做什么

    AI大模型展现惊人能力 有望成为下一代通用技术平台 2010年 麻省理工大学阿齐跌鲁教授等提出了科技发展如何影响人类就业的分析框架 当前 随着以GPT 4为代表的大语言模型的出现 A1开始具备文本生成 语言理解 知识问答 逻辑推理等能力 A
  • 代理HTTP使用不当会出现哪些问题?如何正确使用代理服务?

    代理HTTP是一种常见的网络代理方式 它为客户端和服务器之间提供中间层 转发上下游的请求和响应 正确使用代理HTTP可以提高采集效率 增加网络安全性 加速网络速度 保护用户隐私 但是 使用不当就难以达到预期的效果 在使用代理HTTP服务器时
  • 【VMware】虚拟机中Ubuntu无法连接网络的有效解决办法

    1 Ubuntu网络设置 依次单击 System Settings gt Network gt Wired gt Options 如下图所示 依次选择 General 勾选如下图所示的单选框 最后点击 Save 如下图所示 依次选择 IPv
  • systemctl命令和配置整理

    一 systemctl介绍 systemctl主要负责控制systemd系统和服务管理器 在ubuntu centos等一系列发行版中可用 可以方便的管理需要启动的服务等 可以实现开机自启动 出错重启和定时重启等等功能 二 systemct
  • 在ipad上刷android系统更新,全自动刷安卓4.0 索尼SGPT111刷机教程

    1刷机前 无需自行准备ROM 给Android平板刷机 其实就是给平板电脑换一个新的操作系统 当然 这个操作系统还是Android系统 只是系统界面 内置应用等内容会与之前有所不同 现在网上有很多适用于各种Android手机的Rom 我们可
  • 彩超检查报告单图片_收藏最全甲状腺检查报告解析,你关心的问题都在这!

    现在甲状腺结节患者很多 拿到甲状腺超声检查报告 很多人不太能够看得明白 当问不到专科医生时 免不了会胡乱猜想 频添烦恼 现在就教大家如何看懂超声报告 了解了这些基本信息 可以帮你大致判断病情 并有效地和医生沟通 理解医生给出的建议 如何看懂
  • 人机交互重点知识点

    人机交互重点知识点 1 绪论 1 1什么是人机交互 人机交互是关于设计 评价和实现供人们使用的交互式计算机系统 且围绕这些方面的主要现象进行研究的科学 1 2人机交互的研究内容 1 人机交互界面表示模型与设计方法 2 可用性分析与评估 3
  • vue 实现全屏

    通过引用第三方库 screenfull 实现全屏 1 首先通过 npm install screenfull 执行下载 2 在使用页面进行import screenfull from screenfull 引入 3 然后绑定事件 调用提供的
  • 【第22例】IPD 体系进阶:综合创新地图

    目录 简介 专栏目录 内容 第一步 搭建框架 第二步 构思 第三步 筛选
  • 算法分析

    声明 凡代码问题 欢迎在评论区沟通 承蒙指正 一起成长 目录 一 实验内容与要求 二 概要设计 三 直接上代码 四 运行结果 一 实验内容与要求 内容 布线问题 印刷电路板将布线区域分成n m个方格阵列 精确的电路布线问题要求确定连接方格A
  • 线性表的顺序存储结构(数组插入,删除)——c语言描述

    文章目录 1 线性表的顺序存储结构 1 2 线性表的存储结构的表示 1 2 线性表的操作 OperatorList 1 3 打印线性表 PrintList 1 4 创建线性表 1 5 清零线性表 ClearList 1 6 获取线性表指定位