C语言实现数据结构顺序表

news/2025/11/7 21:51:49/文章来源:https://www.cnblogs.com/tww103/p/19200894

1.顺序表的定义

线性表可分为两种存储结构,一种是顺序存储结构,一种是链式存储结构。一般来说,顺序表是一个相同数据类型的集合,且内存地址一定相邻。在C语言中,一般使用数组实现。

2.顺序表的存储结构

使用结构体来表示顺序表,在结构体中,有两个成员,一个用来存储数据,一个用来表示顺序表的长度

typedef struct {Element data[MAXSIZE];int length;
}List;

3.顺序表的抽象数据结构

​ 抽象数据结构可以表示它的元素以及对应的一些操作

ADT 线性表(List)
Data线性表的数据对象集合为{a_1,a_2,.....,a_n},每个元素的类型均为DataType。其中,除了第一个元素a_1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素a_n外,每一个元素有且只有一个直接后继元素,数据元素之间的关系是一对一的关系
OperationIniList(*L):初始化操作,建立一个空的线性表L。ListEmpty(L):若线性表为空,返回true,反之返回false。ClearList(*L):将线性表清空。GetElem(L,i,*e):将线性表L中的第i个位置元素值返回给e。LocateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素表中序号表示成功;否则,返回0表示失败。ListInsert(*L,i,e):在线性表L中的第i个位置插入新元素e。ListDelete(*L,i,*e):删除线性表L中的第i个位置元素,并用e返回其值。ListLength(L):返回线性表L的元素个数
endADT

4 顺序表的一些操作

这里只简单介绍几种基本操作,如初始化,判断是否为空等等。

4.1顺序表初始化

由于结构定义存储元素的地方是一个静态数组,该数组会在结构声明时由系统自动分配内存空间,所以只需初始化它的长度即可。后面将使用长度来访问该数组。

//初始化顺序表
void InitList(List *l){l->length=0;
}
4.2判断是否为空

当它长度为0时为空表,反之不为空表

//判断表是否为空
bool ListEmpty(List l){if(l.length==0)return true;elsereturn false;
}
4.3返回顺序表的长度

长度由结构中length表示,直接返回即可。若要严谨一点可在前面加上判断if(l==NULL),若它没有初始化则返回错误,但一般我们使用这些函数的前提就是要初始化表

//获取表的长度
int ListLength(List l){return l.length;
}

5.顺序表的插入

该操作将元素e插入到表L的第i个位置上,其中1<=i<=length+1,这里我定义让i从1开始,表示插入的实际位置,而不是下标位置。例如当i为5时,表示我要在表中第5个位置插入元素。但代码中着表示为插入位置是l.data[4]。它可以大于表长度1个位置。比如说表长度是10,则插入位置则是11。这表示在表尾增加元素的操作。下面是算法步骤

1. 检查非法参数,如i不在合理位置或该表已满
2. 从最后一个元素开始,依次往后移,直到位置i
3. 插入元素
4. 增加长度
/*在顺序表第i个位置插入元素x
1<=i<=length+1
返回被插入的顺序表指针
*/
List* InsertList(List *l,int i,Element x){if(i<1 || i>l->length+1 || l->length==MAXSIZE){return NULL;}/*让顺序表的元素,从最后一位开始,依次往后移直到将第i个位置的元素移动到第i+1个位置位置此时,第i个位置就腾了出来*/for(int j = l->length-1; j>=i-1;j--){l->data[j+1]=l->data[j];}l->data[i-1] = x;l->length++;return l;
}

6. 顺序表的删除

​ 将表的第i个位置元素删除,并用参数e带回被删除元素。1<=i<=length,且表不能为空。

/*删除顺序表第i个位置的元素,用e带回
1<=i<=length
*/
Element DeleteList(List *l,int i,Element *e){if(i<1 || i> l->length||ListEmpty(*l)){return -1;}*e = l->data[i-1]; //记录被删除的元素元素/*从第i个位置开始,将第i+1个元素往前覆盖。最后长度-1*/for(int j=i-1;j<=l->length;j++){l->data[j]=l->data[j+1]; //前移}l->length--;return *e;
}

​ 与插入相反的时,删除时需要从第i个位置上往前移动,直接覆盖掉被删除的元素。

7. 顺序表的全部实现

​ 我们将结构、函数声明定义在一个头文件里,并用一个c源文件取实现它。最后在main.c里测试。

1. List.h
#ifndef LIST_H
#define LIST_H
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 50
typedef int Element;typedef struct {Element data[MAXSIZE];int length;
}List;
#endif//初始化顺序表
void InitList(List *l);
//使用数组初始化顺序表,n表示数组的长度
List* arrInitList(List *l,int *arr,int n);
//判断表是否为空
bool ListEmpty(List l);//获取表的长度
int ListLength(List l);//清空顺序表
void ClearList(List *l);/*在顺序表第i个位置插入元素x1<=i<=length+1返回被插入的顺序表指针
*/
List* InsertList(List *l,int i,Element x);/*删除顺序表第i个位置的元素,用e带回1<=i<=length
*/
Element DeleteList(List *l,int i,Element *e);//查看所有元素
void showList(List l);
2.List.c
#include "List.h"//初始化顺序表
void InitList(List *l){l->length=0;
}
//使用数组初始化顺序表,n表示数组的长度
List* arrInitList(List *l,int *arr,int n){if(l==NULL || arr ==NULL || n<1 ||n>MAXSIZE)exit(1); //异常退出for(int i=1;i<=n;i++){//l->data[i]=arr[i];//orInsertList(l,i,arr[i-1]);}l->length=n;return l;
}//判断表是否为空
bool ListEmpty(List l){if(l.length==0)return true;elsereturn false;
}//获取表的长度
int ListLength(List l){return l.length;
}//清空顺序表
void ClearList(List *l){l->length=0;
}/*在顺序表第i个位置插入元素x
1<=i<=length+1
返回被插入的顺序表指针
*/
List* InsertList(List *l,int i,Element x){if(i<1 || i>l->length+1 || l->length==MAXSIZE){return NULL;}/*让顺序表的元素,从最后一位开始,依次往后移直到将第i个位置的元素移动到第i+1个位置位置此时,第i个位置就腾了出来*/for(int j = l->length-1; j>=i-1;j--){l->data[j+1]=l->data[j];}l->data[i-1] = x;l->length++;return l;
}/*删除顺序表第i个位置的元素,用e带回
1<=i<=length
*/
Element DeleteList(List *l,int i,Element *e){if(i<1 || i> l->length||ListEmpty(*l)){return -1;}*e = l->data[i-1]; //记录被删除的元素元素/*从第i个位置开始,将第i+1个元素往前覆盖。最后长度-1*/for(int j=i-1;j<=l->length;j++){l->data[j]=l->data[j+1]; //前移}l->length--;return *e;
}//查看所有元素
void showList(List l){if(ListEmpty(l)){exit(1); //退出并返回错误代码}printf("[");for(int i=0;i<l.length;i++){printf("%d",l.data[i]);if(i<l.length-1)printf(",");}printf("]\n");
}
3.main.c
#include "List.h"int main(int argc, char *argv[]) {List l; //声明一个表,此时才分配空间给结构里的数组int arr[] = {1,8,9,10,5,32,6}; //定义一个数组,用作初始化表arrInitList(&l,arr,7);printf("初始化表:");showList(l);printf("测试插入位置在第一个,插入元素10\n");InsertList(&l,1,10);showList(l);printf("测试插入位置在中间,插入元素50\n");InsertList(&l,5,50);showList(l);printf("测试插入位置在末尾,插入元素100\n");InsertList(&l,ListLength(l)+1,100);printf("表L长度:%d 表元素:",ListLength(l));showList(l);printf("测试删除位置在第一个\n");int e=0;DeleteList(&l,1,&e);printf("被删除的元素:%d\n",e);showList(l);printf("测试删除位置在第4个\n");DeleteList(&l,4,&e);printf("被删除的元素:%d\n",e);showList(l);printf("测试删除位置在第末尾\n");DeleteList(&l,ListLength(l),&e);printf("被删除的元素:%d\n",e);showList(l);
}

其测试结果:

初始化表:[1,8,9,10,5,32,6]
测试插入位置在第一个,插入元素10
[10,1,8,9,10,5,32,6]
测试插入位置在中间,插入元素50
[10,1,8,9,50,10,5,32,6]
测试插入位置在末尾,插入元素100
表L长度:10 表元素:[10,1,8,9,50,10,5,32,6,100]
测试删除位置在第一个
被删除的元素:10
被删除一个元素后的表:[1,8,9,50,10,5,32,6,100]
测试删除位置在第4个
被删除的元素:50
被删除一个元素后的表:[1,8,9,10,5,32,6,100]
测试删除位置在第末尾
被删除的元素:100
被删除一个元素后的表:[1,8,9,10,5,32,6]

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

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

相关文章

AI Compass前沿速览:Cursor 2.0、Firefly Image5、Agent HQ 、LongCat-Video、Kimi-k2 Thinking

AI Compass前沿速览:Cursor 2.0、Firefly Image5、Agent HQ 、LongCat-Video、Kimi-k2 ThinkingAI Compass前沿速览:Cursor 2.0、Firefly Image5、Agent HQ 、LongCat-Video、Kimi-k2 Thinking AI-Compass 致力于构建…

25.11.7联考题解

A 简单题,考虑一个串变化后不同并且计数不重不漏只须保证区间两端不同即可。 B 简单贪心。shopping plans 的超级弱化版。 C 设 \(f_i\) 表示被分在 \(\le i\) 的 L 型的方案数,显然有 \(f_i=\left(\sum_{j=x-i}^{x-…

浅谈dp中的最优化、计数问题

前言 诚然,这东西本来是一个挺好的东西的,但是如果它染上了数学,那么就不那么好了。 我承认,我的分类和题目选取是不够全面、不够有代表性的,因为这只是写给我自己看的。 这东西有三个难点:状态,转移,优化。(…

CF715B

给定 \(n\) 个点 \(m\) 条边的无向图,以及 \(s, t, L\)。每条边有边权(有些被抹去),你要为每个被抹去的边权赋一个正整数值使得 \(s \rightarrow t\) 的最短路为 \(L\)。 \(n, m \le 10^5,L \le 10^9\)首先把所有未…

[NOIP 2001 提高组] 一元三次方程求解

看题目数据范围: 方程存在三个不同实根(根的范围在 −100 至 100 之间) 可以知道这道题其实可以暴力 #include <iostream> #include <cstdio> using namespace std; int main() {double a,b,c,d;scanf(&…

EPnP算法学习随笔

EPnP算法学习随笔这几天刚好在看epnp算法,写篇随笔简要回顾一下。 PnP问题是个很经典的问题,就是根据图像上的关键点来估计相机的位姿,这里主要研究的是单目摄像机,但是值的注意的是单目的精度一般都比较差,因为单…

毒盘未转存仅支持在线观看30s

毒盘未转存仅支持在线观看30s转载,原作者不详 解决方案:控制台里面输入这些代码,回车。 let video = document.querySelectorAll("#html5player_html5_api")[0] video.controls="true" video.p…

Advantech iView SQL注入漏洞分析:认证绕过与数据泄露

本文详细分析了CVE-2022-50594漏洞,涉及Advantech iView SNMP管理工具中的SQL注入漏洞,攻击者可绕过认证窃取包括明文密码在内的用户数据,CVSS评分8.8分。概述 CVE-2022-50594是Advantech iView软件中存在的一个高危…

【机器学习入门】7.1 决策树 —— 像 “判断流程图” 一样做分类 - 教程

【机器学习入门】7.1 决策树 —— 像 “判断流程图” 一样做分类 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: …

P14322 「ALFR Round 11」E 空崎ヒナ 小结

首先把 x 移个项,变成 abs(b[i]-x)。 然后你发现这个东西就是 max a_i 的倍数了。 这个东西很好写,首先你先预处理单调栈和后缀答案。 后缀答案不能在线,于是离线处理。 然后你发现回答询问也不能在线。 于是你再离…

AI元人文:理论自省与客观评估

AI元人文:理论自省与客观评估引言:在理想与现实之间 AI元人文理论作为一种突破性的价值共识框架,其生命力不仅在于理论建构的完整性,更在于持续的自我审视与客观评估。本文旨在以三值纠缠思维为镜,对这一理论体系…

[Element Plus 组件库的官方 API 参考文档] 的部分内容的解释

对于初学者,不需要死记硬背这个 API 文档。更好的学习顺序是:先看组件的基础示例和演示代码 → 模仿着写出能运行的代码 → 有特殊需求时,再回头查这个 API 文档Q1: 除了template是插槽,怎么连el-menu-item都是?…

ZK笔记

1.官网下载地址 https://zookeeper.apache.org/ https://archive.apache.org/dist/zookeeper/ 2.安装步骤 1.安装jdk 2.解压压缩包 tar -xf apache-zookeeper-3.5.7-bin.tar.gz -C /tol/app mv apache-zookeeper-3.5…

完整教程:《以 Trae 为桥:高效集成豆包 1.6 API 的实践与思考》

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

完整教程:Labview项目01:标准可配置序列测试框架

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20251107

每次写类的时候都会觉得发明面向对象的人真是个天才。 今天晚上又稍微写了点,增加了碰撞伤害,现在玩家碰到怪物会回扣怪物.at血量并进入一秒的无敌状态,并且自身颜色变为白色,也是第一次体会到异步的方便之处吧。更…

从零开始实现简易版Netty(十) MyNetty 通用编解码器解决TCP黏包/拆包问题

从零开始实现简易版Netty(十) MyNetty 通用编解码器解决TCP黏包/拆包问题从零开始实现简易版Netty(十) MyNetty 通用编解码器解决TCP黏包/拆包问题 1. TCP黏包拆包问题介绍 在上一篇博客中,lab9版本的MyNetty已经实现…

[Python刷题记录]-除自身以外数组的乘积-普通数组-中等

[Python刷题记录]-除自身以外数组的乘积-普通数组-中等链接:238. 除自身以外数组的乘积 - 力扣(LeetCode) 题目限制不能使用除法,所以开了两个数组listl和listr,listl用来存储i之前的所有数字之乘积,listr用来存…

Transformer Decoder 中序列掩码(Sequence Mask / Look-ahead Mask) - 详解

Transformer Decoder 中序列掩码(Sequence Mask / Look-ahead Mask) - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

P9785 [ROIR 2020] 对常规的斗争 (Day1) 题解

题目传送门 思路 我们不难发现,当区间中没有重复的点很好求,但如果中间部分产生重复的点,他们所产生的贡献会减少。 正着推不好推,那就反着来。 我们可以考虑计算当区间长度确定时,每个区间内每个元素是否出现过。…