【数据结构与算法(C语言)】1. 线性表的顺序存储

文章目录

  • 前言
  • 一. 线性表插入和删除
    • 1. 元素的插入
    • 2. 元素的删除
  • 二. 代码
  • 三. 优缺点

前言

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据结构

一. 线性表插入和删除

1. 元素的插入

在这里插入图片描述
插入位置之后的数据都向后移一位,上图中元素98、208、999、789都向后移一位。元素666插入到第5个位置。

2. 元素的删除

在这里插入图片描述
待删除元素之后所有的元素都向前移一位,上图中,元素209,999,789都向前移一位

二. 代码

#include <stdio.h>
#include <stdlib.h>#define OK 	1
#define ERROR 	0
#define TRUE	1
#define	FALSE	0#define LIST_INIT_SIZE 	20 	/*	线性表初始空间	*/
#define LIST_INCREMENT	10      /*	线性表每次的扩展空间大小 */typedef int Status;	/*	状态码,函数返回的状态码 */
typedef int ElemType;	/*	元素类型,根据需要可以任意修改ElemType的原始类型,此处使用int型	*/typedef struct 
{ElemType* elem ;	/*线性表数据, 使用数组实现顺序存储线性表的数据 */int length;		/*线性表长度*/int listSize;
} SqList;Status InitList(SqList * list);		/*初始化线性表list*/
void DestoryList(SqList * list);		/*销毁线性表list*/
void ClearList(SqList * list);		/*清空线性表list*/
Status ListEmpty(SqList list);		/*判断线性表是否为空表,空表返回TRUE,非空返回FALSE*/
int ListLength(SqList list);		/*返回list的元素个数*/
Status GetElem(SqList list,int i, ElemType * elemPtr);	/*从list中获取第i个元素,并将获取到的元素放到 elemPtr指针中,获取到返回OK,否则返回ERROR */
int LocateElem(SqList list,ElemType elem);		/*在list中查找数据元素elem的位置*/Status PriorElem(SqList list ,ElemType elem, ElemType * elemPtr); /*在list中查找元素elem的前一个元素,并将找到的元素存放到elemPtr指针中*/
Status NextElem(SqList list, ElemType elem, ElemType * elemPtr);  /*在list中查找元素elem的后一个元素,并将找到的元素存放到elemPtr指针中*/
Status ListInsert(SqList * list,int i,ElemType elem);		/*在list的第i个位置插入元素elem*/
Status ListDelete(SqList * list,int i,ElemType * elemPtr);	/*在list中删除第i个元素,并将第i个元素存放到elemPtr指针中*/Status Visit(ElemType elem);   /*对elem操作 */ 
Status ListTraverse(SqList list,Status (*visit)(ElemType));		/* 遍历表 */
Status ListUnion(SqList * listA,SqList listB);	/* 将listB 中的数据合并到listA中	*/
int main()
{int i,j;SqList list,listA,listB;ElemType  elem;InitList(&list);InitList(&listA);InitList(&listB);if(!ListTraverse(list,Visit))printf("list没有数据打印!\n");for(i=0;i<9;i++){ListInsert(&list,i+1,i+100);ListInsert(&listA,i+1,i+200);}for(i=5;i<30;i++)ListInsert(&listB,i+1,i+200);/* i=26的时候,listB的数量超过20个,会将存储空间扩容*/printf("list的数据:\t");ListTraverse(list,Visit); if(PriorElem(list,103,&elem))printf("103前面的一个数字为;%d\n",elem);if(NextElem(list,103,&elem))printf("103后面的一个数字为:%d\n",elem);printf("在第2个位置插入999\n");ListInsert(&list,2,999);printf("list的数据:\t");ListTraverse(list,Visit); ListDelete(&list,5,&elem);printf("删除第5个数字:%d\n",elem);printf("list的数据:\t");ListTraverse(list,Visit);i=ListUnion(&listA,listB); /*将listB数据合并到listA中*/j=4;printf("listA的数据为:\n");ListTraverse(listA,Visit);DestoryList(&listA);  	    /*销毁listA,释放地址*/DestoryList(&listB);DestoryList(&list);return 0;}/*初始化线性表list*/
Status InitList(SqList *list)
{list->elem = (ElemType*) malloc(LIST_INIT_SIZE*sizeof(ElemType));if(list->elem == NULL)return ERROR;list->length = 0;list->listSize = LIST_INIT_SIZE;return OK;
} /*销毁线性表list*/
void DestoryList(SqList * list)
{free(list->elem);list->elem = NULL;list->length = 0;list->listSize = 0;
}/*清空线性表list*/
void ClearList(SqList * list){list->length=0;
}/*判断线性表是否为空表,空表返回TRUE,非空返回FALSE*/
Status ListEmpty(SqList list){if(list.length>0)return FALSE;else return TRUE;}/*返回list的元素个数*/
int ListLength(SqList list){return list.length;
}/*从list中获取第i个元素,并将获取到的元素放到 elemPtr指针中,  获取到返回OK,否则返回ERROR */
Status GetElem(SqList list,int i,ElemType * elemPtr){if(list.length==0 || i<1 || i>list.length)return ERROR;*elemPtr= list.elem[i-1];return OK;
}/*在list中查找第一个和elem相等的元素的位置,如果没有找到,返回ERROR,即0 */
int LocateElem(SqList list,ElemType elem)
{int i=0;for(; i<list.length; i++)if(list.elem[i]==elem)return i+1;return ERROR;
}/*在list中查找元素elem的前一个元素,并将找到的元素存放到elemPtr指针中*/
Status PriorElem(SqList list,ElemType elem,ElemType * elemPtr){int i;for(i=1 ; i<list.length; i++)/*第一个元素i=0没有前导,所以从第二个元素i=1开始*/{if(list.elem[i]==elem ){*elemPtr=list.elem[i-1];return OK;}}return ERROR;}/*在list中查找元素elem的后一个元素,并将找到的元素存放到elemPtr指针中*/
Status NextElem(SqList list, ElemType elem, ElemType * elemPtr)
{int i;for( i=0; i<list.length-1; i++)/*最后一个元素没有后驱元素,所以查找到倒数第二个元素就结束(下标为list.length-2)*/{if(list.elem[i]==elem && i<list.length-1){*elemPtr=list.elem[i+1];return OK;}}return ERROR;
}/*在list的第i个位置插入元素elem*/Status ListInsert(SqList * list,int i,ElemType elem){int j;ElemType * base;if(i<1) return ERROR;if(list->length==list->listSize)/*list满了,需要对list扩容*/{base=(ElemType *) realloc(list->elem,(list->listSize+LIST_INCREMENT)*sizeof(ElemType));if(base!=NULL){  	/*扩容成功,将新的基地址赋值给list->elem,并更新list的存储空间listSize*/list->listSize += LIST_INCREMENT;list->elem=base;}else return ERROR;}for(j=list->length-1; j>=i-1; j--) /* 从第i个数据开始,所有元素向后移一位 */ list->elem[j+1]=list->elem[j];list->elem[j+1]=elem;		   /*在第i个位置的值更新为新值elem, 此时的j=i-2, j+1=i-1,data[j+1]的位置就是第i个元素位置 */list->length++;return OK;}/*在list中删除第i个元素,并将第i个元素存放到elemPtr指针中*/Status ListDelete(SqList * list,int i,ElemType * elemPtr) 
{int j;if(i<1 || i>list->length)return ERROR;*elemPtr=list->elem[i-1];for(j=i-1; j<list->length-1; j++)list->elem[j]=list->elem[j+1];list->length--;return OK;
}	/*对elem操作,具体什么操作可以根据需要修改,本示例中是打印elem的值*/
Status Visit(ElemType elem){printf("%d\t",elem);
}/*遍历线性表,并对每一个元素调用Visit函数,一旦Visit()失败,这遍历失败 */
Status ListTraverse(SqList list, Status(*Visit) (ElemType elem) ){int i;if(list.length==0)return ERROR;for(i=0;i<list.length;i++)(*Visit)(list.elem[i]);printf("\n");return OK;
}/* 将listB 中的数据合并到listA中,B的元素已经在A中存在,不重复插入 */Status  ListUnion(SqList * listA,SqList listB){int i ;ElemType  elem;for(i=1; i<=listB.length; i++) /*循环listB所有元素 */{if( GetElem(listB,i,&elem) && !LocateElem(*listA,elem))/*在获取listB的元素,存放到变量elem中,在 listA中查找elem,不存在插入*/ListInsert(listA,listA->length+1,elem);}return OK;}	 

三. 优缺点

优点:读取快
缺点:插入和删除需要移动大量元素; 存储空间会有浪费的情况

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

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

相关文章

银行业ESB架构:构建安全高效的金融信息交换平台

在金融行业&#xff0c;信息交换是银行业务运作的核心。为了实现不同系统之间的数据交互和业务流程的协同&#xff0c;银行通常采用企业服务总线&#xff08;ESB&#xff09;架构。本文将探讨银行业ESB架构的设计理念、关键技术以及实践经验&#xff0c;帮助银行构建安全高效的…

《软件过程与管理》复习

《软件过程与管理》复习 1 高质量编程及测试 1.1 如何选择正确的评审方法 选择评审方法最有效的标准是&#xff1a; “对于最可能产生风险的工作成果&#xff0c;要采用最正式的评审方法.” 例如&#xff1a;核心代码的失效也会带来很严重的后果&#xff0c;所以也应该采用…

【Unity学习笔记】第十四 Prefab 概念解惑

目录 1 prefab、prefab变体、prefab覆盖和prefab 嵌套2 connect 与unpack3 prefab到底是什么&#xff0c;它和gameobject又有什么区别&#xff1f;4 为什么要用prefab&#xff1f;5 代码动态加载prefab6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null7 Prefab…

卫浴品牌商家做展示预约小程序的作用是什么

卫浴品牌类别多、普通/智能、场景化等&#xff0c;无论企业还是经销商市场门店都比较饱满&#xff0c;虽然市场需求度高&#xff0c;但同样需要商家不断拓宽销售渠道和挖掘客户价值&#xff0c;破圈增长。 线上多平台发展尤为重要&#xff0c;而小程序作为连接点&#xff0c;对…

PostgreSQL的学习心得和知识总结(一百三十九)|深入理解PostgreSQL数据库GUC参数 allow_alter_system 的使用和原理

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

C++ //练习 14.2 为Sales_data编写重载的输入、输出、加法和复合赋值运算符。

C Primer&#xff08;第5版&#xff09; 练习 14.2 练习 14.2 为Sales_data编写重载的输入、输出、加法和复合赋值运算符。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /************************************************…

Windows使用bat远程操作Linux并执行命令

背景&#xff1a;让客户可以简单在Windows中能自己执行 Linux中的脚本&#xff0c;傻瓜式操作&#xff01; 方法&#xff1a;做一个简单的bat脚本&#xff01;能远程连接到Linux&#xff0c;并执行Linux命令&#xff01;客户双击就能使用&#xff01; 1、原先上网查询到使用P…

Java | Leetcode Java题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; public class Solution {public boolean canJump(int[] nums) {int n nums.length;int rightmost 0;for (int i 0; i < n; i) {if (i < rightmost) {rightmost Math.max(rightmost, i nums[i]);if (rightmost > n - 1) {retu…

社交技巧:网络社交有哪些优点?

既然网络社交已经成为了我们进行社交的一个必不可少的方式&#xff0c;那今天就来和大家分析一下&#xff0c;网络社交有哪些优点&#xff0c;以帮助大家更恰当地使用社交媒体 1.拓展更多的关系机会 有很多人在现实生活中可能过于内向腼腆&#xff0c;有社交焦虑&#xff0c;这…

C#-快速剖析文件和流,并使用(持续更新)

目录 一、概述 二、文件系统 1、检查驱动器信息 2、Path 3、文件和文件夹 三、流 1、FileStream 2、StreamWriter与StreamReader 3、BinaryWriter与BinaryReader 一、概述 文件&#xff0c;具有永久存储及特定顺序的字节组成的一个有序、具有名称的集合&#xff1b; …

Pandas dataframe 中显示包含NaN值的单元格

大部分教程只讲如何打印含有NA的列或行。这个函数可以直接定位到单元格&#xff0c;当dataframe的行和列都很多的时候更加直观。 # Finding NaN locations for df.loc def locate_na(df):nan_indices set()nan_columns set()for col, vals in df_descriptors.items():for in…

小米汽车充电枪继电器信号

继电器型号&#xff1a; 参考链接 小米SU7&#xff0c;便捷充放电枪拆解 (qq.com)https://mp.weixin.qq.com/s?__bizMzU5ODA2NDg4OQ&mid2247486086&idx1&sn0dd4e7c9f7c72d10ea1c9f506faabfcc&chksmfe48a110c93f2806f6e000f6dc6b67569f6e504220bec14654ccce7d…

Qt 6 开源版(免费) -- 安装图解

Qt6起&#xff0c;两项重大改变&#xff08;并非指技术&#xff09;&#xff1a; 必须在线安装&#xff0c;不再提供单独的安装包主推收费的商业版 当然的&#xff0c;为了引流、培养市场&#xff0c;提供了一个免费的开源版本。 开源版相对于收费的商业版&#xff0c;主体是…

【YOLO改进】换遍IoU损失函数之SIoU Loss(基于MMYOLO)

SIoU损失函数 论文链接:https://arxiv.org/pdf/2205.12740 SIoU&#xff08;Simplified IoU&#xff09;损失函数是一种基于IoU&#xff08;Intersection over Union&#xff09;的改进损失函数&#xff0c;主要用于目标检测任务中的边界框回归。与传统的IoU损失函数相比&…

linux运行python怎么结束

假如你已经进入到【>>>】&#xff0c;那么输入【quit&#xff08;&#xff09;】&#xff0c;然后按一下回车键即可退出了。 如果是想要关闭窗口的&#xff0c;那么直接在这个窗口上按【ctrld】。

AI项目二十:基于YOLOv8实例分割的DeepSORT多目标跟踪

若该文为原创文章&#xff0c;转载请注明原文出处。 前面提及目标跟踪使用的方法有很多&#xff0c;更多的是Deepsort方法。 本篇博客记录YOLOv8的实例分割deepsort视觉跟踪算法。结合YOLOv8的目标检测分割和deepsort的特征跟踪&#xff0c;该算法在复杂环境下确保了目标的准…

FPM 快速报表开发

背景&#xff1a; 使用FPM开发报表时&#xff0c;如果报表字段过多&#xff0c;页面拖拽等操作不方便 报表数量过多时&#xff0c;新建应用操作步骤较为繁琐 更习惯通过少量代码而非页面操作去实现功能 处理&#xff1a; 将FPM报表开发简化为类似GUI端ALV的开发过程:&#xff…

秋招后端开发面试题 - Java语言基础(上)

目录 Java基础上前言面试题Java 语言的特点JVM JDK JRE什么是跨平台性&#xff1f;原理是什么&#xff1f;什么是字节码?采用字节码的好处是什么?Java 和 C 的区别&#xff1f;注释&#xff1f;关键字关键字 instanceof类型转换关键字 this 和 super关键字 final finally fin…

【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 打家劫舍 II(难度⭐⭐)(67)

1. 题目解析 题目链接&#xff1a;213. 打家劫舍 II 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 这个问题是经典的“打家劫舍”问题的变种&#xff0c;原问题是在单排房屋中进行偷窃&#xff0c;而这个问题则是在…

【论文精读】多模态系列:ALBEF、VLMo、BLIP、CoCa、BeiTv3

系列文章目录 【论文精读】CLIP&#xff1a;Learning Transferable Visual Models From Natural Language Supervision 从自然语言监督中学习可迁移的视觉模型 论文精读】CLIP 改进工作&#xff08;LSeg、GroupViT、VLiD、 GLIPv1、 GLIPv2、CLIPasso、CLIP4clip、ActionCLIP&…