数据结构-Data Structure (顺序表专题)
标题数据结构概念数据结构是计算机存储、组织数据的方式。它是指相互之间存在⼀种或多种特定关系的数据元素的集合。分为线性结构和非线性结构。程序中如果不对数据进⾏管理可能会导致数据丢失、操作数据困难、野指针等情况。通过数据结构能够有效将数据组织和管理在⼀起。按照自己的方式可以任意对数据进行增删改查等操作。线性结构概念线性结构是数据元素之间存在一对一线性关系的数据结构所有元素按前后次序排成一条连续的 “线性序列”。线性结构在物理结构上不一定是连续的但在逻辑结构上一定是连续的。常见类型顺序表列表栈队列字符串,,,顺序表概念顺序表是采用一段连续的内存空间依次存储数据元素的线性结构基于数组实现元素的逻辑顺序与物理存储顺序完全一致。分类静态顺序表概念使用定长数组存储元素。#define N 100 typedef struct Seqlist { int arr[N]; //定长数组 int size; //定义有效数据的个数 }SL;动态顺序表typedef struct Seqlist { int* arr; //定长数组 int size; //定义有效数据的个数 int capacity; //定义可变空间大小 }SL;动态顺序表的实现创建//定义顺序表的结构 typedef int SLtype; //定义宏 顺序表类型 //定义动态顺序表 typedef struct Seqlist { SLtype* arr; SLtype size; SLtype capacity; }SL;初始化//初始化 void SLinit(SL* ps); //定义指针变量来接受地址传参进行初始化 void SLinit(SL* ps) { ps-arr NULL; ps-size ps-capacity 0; }打印//打印 void SLprint(SL s); void SLprint(SL s) { for ( int i 0; i s.size; i) { printf(%d , s.arr[i]); } printf(\n); }插入//插入 void SLpushback(SL* ps, SLtype x); //尾部插入 void SLpushfront(SL* ps, SLtype x); //头部插入 void checkcapacity(SL* ps) { if (ps-capacity ps-size) //如果相等需要申请空间 { //malloc calloc relloc- 涉及增容 //三目表达式 //将初始化的capacity空间大小设值,若为0初始化为4若不为0设值为两倍增容 int newcapacity ps-capacity 0 ? 4 : 2 * ps-capacity; //增容一般使用倍数增容方式这里使用最常见的两倍增容。 SLtype* tmp (SLtype*)realloc(ps-arr, newcapacity * 2 * sizeof(SLtype)); if (tmp NULL) { perror(realloc fail!); exit(1); } ps-arr tmp; ps-capacity newcapacity; } } void SLpushback(SL* ps, SLtype x) { /*ps-arr[ps-size] x; ps-size;*/ /*if (ps NULL) { return; }*/ assert(ps); //判断空间大小是否足够 checkcapacity(ps); ps-arr[ps-size] x; } void SLpushfront(SL* ps, SLtype x) { assert(ps); checkcapacity(ps); //将顺序表数据整体向后挪动 for ( int i ps-size ;i0;i--) { ps-arr[i] ps-arr[i - 1]; } ps-arr[0] x; ps-size; }删除//删除 void SLpopback(SL* ps); //尾部删除 void SLpopfront(SL* ps); //头部删除 void SLpopback(SL* ps) { assert(ps); //判断顺序表是否为空 assert(ps-size); //ps-arr[ps-size - 1] -1; --ps-size; } void SLpopfront(SL* ps) { assert(ps); assert(ps-size); for ( int i 0; i ps-size-1; i) { ps-arr[i] ps-arr[i 1]; } ps-size--; }销毁//销毁 void SLdestroy(SL* ps); void SLdestroy(SL* ps) { if (ps-arr) { free(ps-arr); } ps-arr NULL; ps-size ps-capacity 0; }指定位置插入//指定位置插入 void SLInsert(SL* ps, int pos, SLType x); void SLInsert(SL* ps, int pos, SLType x) { assert(ps); assert(pos 0 pos ps-size); SLCheckCapacity(ps); for (int i ps-size; i pos; i--) { ps-arr[i] ps-arr[i - 1]; } ps-arr[pos] x; ps-size; }指定位置删除//指定位置删除 void SLErase(SL* ps, int pos); void SLErase(SL* ps, int pos) { assert(ps); assert(pos 0 pos ps-size); for (int i pos; i ps-size-1; i) { ps-arr[i] ps-arr[i 1]; } ps-size--; }查找//查找 int SLFind(SL* ps, SLType x); int SLFind(SL* ps, SLType x) { assert(ps); for ( int i 0; i ps-size; i) { if (ps-arr[i] x) { return i; } } return -1; } //测试 int find SLFind(s1,3); if (find 0) { printf(no found!); } else { printf(find it! The subscript is %d, find); }完整代码如下1. 顺序表头文件 seqlist.h 定义#pragma once #include stdio.h #include stdlib.h #include assert.h //顺序表 //创建 typedef int SLType; //指定类型 typedef struct seqlist { SLType* arr; int size; int capacity; }SL; //指定顺序表名称为SL //初始化 void SLInit(SL* ps); //打印 void SLPrint(SL s); //销毁 void SLDestroy(SL* ps); //头插 void SLPushFront(SL* ps,SLType x); //尾插 void SLPushBack(SL* ps, SLType x); //头删 void SLPopFront(SL* ps); //尾删 void SLPopBack(SL* ps); //指定位置插入 void SLInsert(SL* ps, int pos, SLType x); //指定位置删除 void SLErase(SL* ps, int pos); //查找 int SLFind(SL* ps, SLType x);2.执行源文件seqlist.c#define _CRT_SECURE_NO_WARNINGS 1 #include seqlist.h //初始化 void SLInit(SL* ps) { ps-arr NULL; ps-capacity ps-size 0; } //打印 void SLPrint(SL s) { for (int i 0; i s.size; i) { printf(%d , s.arr[i]); } printf(\n); } //销毁 void SLDestroy(SL* ps) { if (ps-arr) { free(ps-arr); } ps-size ps-capacity 0; } //申请空间 void SLCheckCapacity(SL* ps) { if (ps-sizeps-capacity) { int newcapacity ps-capacity 0 ? 4 : 2 * ps-capacity; SLType* tmp (SLType*)realloc(ps-arr, newcapacity*sizeof(SLType)); if (tmp NULL) { perror(realloc fail!); } ps-arr tmp; ps-capacity newcapacity; } } //头插 void SLPushFront(SL* ps, SLType x) { //申请空间 assert(ps); SLCheckCapacity(ps); for (int ips-size;i0;i--) { ps-arr[i] ps-arr[i - 1]; } ps-arr[0] x; ps-size; } //尾插 void SLPushBack(SL* ps, SLType x) { assert(ps); SLCheckCapacity(ps); ps-arr[ps-size] x; } //头删 void SLPopFront(SL* ps) { assert(ps); assert(ps-size); for (int i 0; i ps-size-1; i) { ps-arr[i] ps-arr[i 1]; } ps-size--; } //尾删 void SLPopBack(SL* ps) { assert(ps); assert(ps-size); --ps-size; } //指定位置插入 void SLInsert(SL* ps, int pos, SLType x) { assert(ps); assert(pos 0 pos ps-size); SLCheckCapacity(ps); for (int i ps-size; i pos; i--) { ps-arr[i] ps-arr[i - 1]; } ps-arr[pos] x; ps-size; } //指定位置删除 void SLErase(SL* ps, int pos) { assert(ps); assert(pos 0 pos ps-size); for (int i pos; i ps-size-1; i) { ps-arr[i] ps-arr[i 1]; } ps-size--; } //查找 int SLFind(SL* ps, SLType x) { assert(ps); for ( int i 0; i ps-size; i) { if (ps-arr[i] x) { return i; } } return -1; }3.测试文件test.c#define _CRT_SECURE_NO_WARNINGS 1 #include seqlist.h void test01() { SL s1; SLInit(s1); SLPushBack(s1, 1); SLPushBack(s1, 2); SLPrint(s1); SLPushFront(s1, 3); SLPushFront(s1, 4); SLPrint(s1); SLPopBack(s1); SLPrint(s1); SLPopFront(s1); SLPrint(s1); SLInsert(s1, 0, 6); SLPrint(s1); SLInsert(s1,s1.size, 9); SLPrint(s1); SLInsert(s1, 1, 7); SLPrint(s1); SLErase(s1, 3); SLPrint(s1); SLErase(s1, s1.size); SLPrint(s1); SLErase(s1, 0); SLPrint(s1); int find SLFind(s1,3); if (find 0) { printf(no found!); } else { printf(find it! The subscript is %d, find); } } int main() { test01(); return 0; }代码运行结果如下图所示通讯录项目数据结构设计定义通讯录中联系人的结构体如姓名、电话、地址等字段顺序表的存储结构及容量管理策略静态数组或动态扩容核心功能实现初始化通讯录分配内存或设置初始容量添加联系人检查容量并插入数据删除联系人查找并移除数据处理后续元素移位查找联系人按姓名或关键字遍历搜索修改联系人信息定位后更新字段显示所有联系人遍历输出代码实现定义通讯录结构体 c.h#pragma once //定义通讯录联系人结构体 //姓名 性别 年龄 电话 地址 #define NM 20 #define GM 10 #define AM #define TM 20 #define ADM 100 typedef struct PersonInfo { char name[NM]; char gender[GM]; int age; char tel[TM]; char addr[ADM]; }Peo;在顺序表头文件当中指定类型 s.htypedef Peo SLType; //指定类型对通讯录进行操作 c.h//对通讯录进行操作 // //前置声明 typedef struct seqlist contact; //初始化 void ContactInit(contact* con); //销毁 void ContactDestroy(contact* con); //插入数据 void ContactInsert(contact* con); //删除数据 void ContactErase(contact* con); //修改数据 void ContactModify(contact* con); //查找数据 void ContactFind(contact* con); //打印显示 void ContactShow(contact* con);通讯录初始化 .cvoid ContactInit(contact* con) { SLInit(con); //直接调用即可 }添加数据void ContactAdd(contact* con) { //获取用户输入信息 姓名 性别 年龄 电话 住址 Peo info; printf(please input name:\n); scanf(%s, info.name); printf(please input gender:\n); scanf(%s, info.gender); printf(please input age:\n); scanf(%d, info.age); printf(please input telephone:\n); scanf(%s, info.tel); printf(please input address:\n); scanf(%s, info.addr); //添加数据 SLPushBack(con, info); }删除数据int FindName(contact* con,char name[]) { for (int i 0; i con-size; i) { if (0 strcmp(con-arr[i].name,name)) //找到 { return i; } } return -1; //没有找到 } void ContactErase(contact* con) { char name[NM]; printf(please input name that need delete:\n); scanf(%s, name); //利用查找方式判断数据是否存在 int find FindName(con, name); if (find 0) { printf(not found!\n); return; } SLErase(con, find); //根据返回下标执行删除 printf(delete done!\n); }修改数据void ContactModify(contact* con) { char name[NM]; printf(please input name that need modify:\n); scanf(%s, name); int find FindName(con, name); if (find 0) { printf(not found!\n); return; } printf(please input new name:\n); scanf(%s, con-arr[find].name); printf(please input new gender:\n); scanf(%s, con-arr[find].gender); printf(please input new age:\n); scanf(%d, con-arr[find].age); printf(please input new telephone:\n); scanf(%s, con-arr[find].tel); printf(please input new address:\n); scanf(%s, con-arr[find].addr); }查找数据void ContactFind(contact* con) { char name[NM]; printf(please input name that need find\n); scanf(%s, name); int find FindName(con, name); if (find 0) { printf(not found!\n); return; } //表头打印 printf(%s %s %s %s %s\n, 姓名, 性别, 年龄, 电话, 住址); printf(%s %s %d %s %s\n, con-arr[find].name, con-arr[find].gender, con-arr[find].age, con-arr[find].tel, con-arr[find].addr ); }展示数据void ContactShow(contact* con) { printf(%s %s %s %s %s\n, 姓名, 性别, 年龄, 电话, 住址); for (int i 0; i con-size; i) { printf(%s %s %d %s %s\n, con-arr[i].name, con-arr[i].gender, con-arr[i].age, con-arr[i].tel, con-arr[i].addr ); } }通讯录销毁void ContactDestroy(contact* con) { SLDestroy(con); }建立通讯录菜单void menu() { printf(*******************通讯录******************\n); printf(********1.添加联系人 2.删除联系人*********\n); printf(********3.修改联系人 4.查找联系人*********\n); printf(********5.展示联系人 0.退出系统 *********\n); printf(*******************************************\n); }部分效果展示主函数执行代码如下int main() { int op -1; contact con; ContactInit(con); do{ menu(); printf(please choose a option!\n); scanf(%d, op); switch (op) { case 1: ContactAdd(con); break; case 2: ContactErase(con); break; case 3: ContactModify(con); break; case 4: ContactFind(con); break; case 5: ContactShow(con); break; case 0: printf(exit!\n); break; default: break; } } while (op !0 ); ContactDestroy(con); return 0; }

相关新闻

免费PDF工具实测:PDF补丁丁三步上手,书签合并提取一次搞定

免费PDF工具实测:PDF补丁丁三步上手,书签合并提取一次搞定

免费PDF工具实测:PDF补丁丁三步上手,书签合并提取一次搞定 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等 项目地…

2026/10/13 9:28:36 阅读更多 →
mini小巧-WIFI-温湿度检测

mini小巧-WIFI-温湿度检测

项目简介mini小巧-WIFI-温湿度检测使用STC8G1K08A 大夏龙雀WIFI模块EPS8266蓝牙,搭配AHT30 温湿度模块,通过使用MQTT协议上传数据。本设计简单易上手归于大夏龙雀wifi/蓝牙二合一模块集成TCP/UDP/MQTT 协议通信省去繁杂程序开发与测试。项目功能本设计是…

2026/9/29 12:12:13 阅读更多 →
每天更新114个:这份公共Tracker服务器列表,是怎么把BT下载从“0KB/s“救回来的

每天更新114个:这份公共Tracker服务器列表,是怎么把BT下载从“0KB/s“救回来的

每天更新114个:这份公共Tracker服务器列表,是怎么把BT下载从"0KB/s"救回来的 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist 那天晚上十一…

2026/9/29 3:24:58 阅读更多 →

最新新闻

基于STM32单片机电磁波检测电磁辐射保护云平台视频监控蓝牙无线APP/WiFi无线APP/摄像头视频监控/云平台设计S446

基于STM32单片机电磁波检测电磁辐射保护云平台视频监控蓝牙无线APP/WiFi无线APP/摄像头视频监控/云平台设计S446

STM32-S446-电磁波检测舵机保护报警频率变化预警阈值保护阈值超阈值报警OLED屏声光提醒按键(无线方式选择)产品功能描述:本系统由STM32F103C8T6单片机核心板、OLED屏、(无线蓝牙/无线WIFI/无线视频监控/联网云平台模块-可选)、电磁波检测模块…

2026/10/13 9:29:07 阅读更多 →
基于Node.js+Vue的前后端分离管理系统开发全记录

基于Node.js+Vue的前后端分离管理系统开发全记录

先说一下背景。去年学校就业办找我做一个大学生创业项目申报评比系统,要求是学生能在线上报项目材料,评委能在线打分评审,管理员能配置评审指标并导出最终排名。技术栈指定了Node.js Vue,前后端分离。这活儿听起来简单&#xff0…

2026/10/13 9:29:07 阅读更多 →
SonarQube 7.9 稳定落地实践:H2部署、规则XML化与IDE深度集成

SonarQube 7.9 稳定落地实践:H2部署、规则XML化与IDE深度集成

简介:本资源为SonarQube 7.9版本官方发行版压缩包(ZIP格式),面向Java/全栈开发工程师、DevOps工程师及代码质量保障团队,用于搭建本地或测试环境的静态代码分析平台,解决代码漏洞识别、技术债务量化与编码规…

2026/10/13 9:29:07 阅读更多 →
Hudi 多表事务(Multi-Table Transactions)设计解读:数据库时间线、冲突检测与事务协议

Hudi 多表事务(Multi-Table Transactions)设计解读:数据库时间线、冲突检测与事务协议

大数据数据湖数据工程 【免费下载链接】hudi Upserts, Deletes And Incremental Processing on Big Data. 项目地址: https://gitcode.com/gh_mirrors/hu/hudi 点击查看 免费下载 本篇技术指南围绕 Hudi 社区 RFC-73(JIRA HUDI-6709)展开&am…

2026/10/13 9:29:07 阅读更多 →
scrcpy 完全指南:3 分钟免费把手机屏幕投到电脑并直接操控

scrcpy 完全指南:3 分钟免费把手机屏幕投到电脑并直接操控

scrcpy 完全指南:3 分钟免费把手机屏幕投到电脑并直接操控 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy scrcpy 是一款免费开源的安卓投屏与控屏工具:手机屏幕镜像…

2026/10/13 9:29:07 阅读更多 →
django-crispy-forms 版本历史完全指南:2.0 破坏性变更、兼容性矩阵与源码级验证

django-crispy-forms 版本历史完全指南:2.0 破坏性变更、兼容性矩阵与源码级验证

后端 【免费下载链接】django-crispy-forms The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML…

2026/10/13 9:28:07 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →