C语言_数据结构总结2:动态分配方式的顺序表
0——静态分配内存的顺序表和动态分配内存的顺序表的相同之处和不同之处
相同之处
-
基本操作逻辑相同:无论是静态分配还是动态分配的顺序表,其核心的操作逻辑是一致的。例如插入操作都需要将插入位置之后的元素依次后移,删除操作都需要将删除位置之后的元素依次前移,查找操作也都是通过遍历或者直接定位来完成。
-
数据元素存储方式相同:两种顺序表都是将数据元素依次存储在连续的内存空间中,都可以通过数组下标来直接访问元素,时间复杂度为 \(O(1)\)。
-
功能用途相同:都用于实现线性表的功能,支持数据的插入、删除、查找等基本操作。
不同之处
-
内存分配方式:
-
静态分配:在编译时就确定了顺序表的最大容量,使用数组来存储元素,数组的大小在程序运行过程中不能改变。
-
动态分配:在程序运行时根据需要动态地分配内存空间,可以通过
malloc、realloc等函数来调整顺序表的容量。
-
-
内存管理:
-
静态分配:不需要手动管理内存,数组的内存空间由系统自动分配和释放。
-
动态分配:需要手动管理内存,使用
malloc分配内存,使用free释放内存,否则会造成内存泄漏。
-
-
表长限制:
-
静态分配:顺序表的最大长度是固定的,一旦达到最大长度就无法再插入新的元素。
-
动态分配:可以根据需要动态地调整顺序表的容量,理论上只要系统有足够的内存,就可以不断地插入新的元素。
-
纯C语言代码,不涉及C++
代码实现
0. 变量声明
#include<stdio.h>
#include<stdlib.h>
#define InitSize 50 //初始容量
#define Increment 10 //每次扩容的增量
typedef int ElemType;
typedef struct SeqList {
ElemType* data; //动态分配数组的指针
int length; //顺序表当前的长度(元素个数)
int capacity; //顺序表当前容量
}SeqList;
1.初始化
void InitSeqList(SeqList* L) {L->data = (ElemType*)malloc(sizeof(ElemType) * InitSize);if (L->data == NULL){printf("内存分配失败!\n");exit(1); // 退出系统操作}L->length = 0;L->capacity = InitSize;
}
2.扩容
void IncreaseCapacity(SeqList* L) {ElemType* newData = (ElemType*)realloc(L->data,(sizeof(ElemType)) * (InitSize + Increment));if (newData == NULL){printf("内存分配失败!\n");exit(1); // 退出系统操作}L->data = newData;L->capacity += Increment;
}
3.插入
即:在第pos个位置插入value值,即在数组下标pos-1的位置插入value值
int InsertSeqList(SeqList* L,int pos ,ElemType value) {//1.判断插入位置是否合法if (pos < 1 || pos > L->length + 1){printf("插入位置不合法!\n");return -1;}//2.判断顺序表存储空间是否满了if (L->length >= L->capacity){IncreaseCapacity(L); //空间不足,进行扩容操作}//3.将第pos个位置及往后的元素都后移一个位置,空出第pos个位置(这里采用逆序遍历)for(int i = L->length; i >= pos; i++){L->data[i] = L->data[i - 1];}//4.插入数据L->data[pos - 1] = value;//5.表长加1L->length++;return 0; //插入成功
}
4.按位查找
即:返回第pos个位置对应的value值
int findValueByPos(SeqList* L, int pos, ElemType* value) {//1.判断要查找的位置是否合理if (pos < 1 || pos > L->length){printf("查找位置不在当前顺序表范围内!\n");}//2.查找第pos个位置对应的value值*value = L->data[pos - 1];return 0; //查找成功
}
5.按值查找
即:返回value值对应的位序,即第几个,下标是位序减1
int findPosByValue(SeqList* L, ElemType value) {for (int i = 0; i < L->length ; i++){if (L->data[i] == value) {return i + 1;}}return -1; //未在该顺序表中找到该值
}
6.删除
即:将第pos个的值赋值交给value变量存储后腾开第pos个位置
然后将第pos个后的数据都往前移动一个位置,填补第pos个位置
int deleteSeqList(SeqList* L, int pos,ElemType* value) {//1. 判断删除位置是否合理,即是否在存有数据的范围内if (pos < 1 || pos > L->length){printf("待删除位置不在合理范围内!\n");return -1; }//2. 判断空间是否为空if (L->length == 0){printf("当前空间未存有数据,无法完成删除操作!\n");}//3.将要被删除的数据赋值(转存于)value变量*value = L->data[pos - 1];//4.将第pos个位置往后的元素都往前挪一个位置for (int i = pos; i < L->length; i++){L->data[i - 1] = L->data[i];}//5.表长减1L->length--;return 0; //删除成功
}
7.注销
void destroySeqList(SeqList* L) {if (L->data != NULL){free(L->data);L->data = NULL;L->length = 0;L->capacity = 0;}
}
8.打印
void printSeqList(SeqList* L) {if (L->length == 0){printf("当前顺序表为空!\n");}else {for (int i = 0; i < L->length ; i++){if (i == L->length - 1) {printf("%d", L->data[i]);}else{printf("%d ", L->data[i]);}}printf("\n");}printf("--------------------------------------------------\n");
}
9.测试代码
int main() {SeqList L;InitSeqList(&L);//插入数据测试if (InsertSeqList(&L,1,18) != 0){printf("插入失败!\n");}if (InsertSeqList(&L,2,7) != 0){printf("插入失败!\n");}if (InsertSeqList(&L,3,34) != 0){printf("插入失败!\n");}printSeqList(&L); // 18 7 34//删除数据测试ElemType value;if (deleteSeqList(&L, 2, &value) != 0){printf("删除失败!\n");}printSeqList(&L); // 18 34//按位查找测试,查找第1位的值是什么ElemType val;if (findValueByPos(&L,1,&val) == 0){printf("第1位的数据为:%d\n", val); //第1位的数据为:18}else{printf("查找失败!\n");}//按值查找测试,查找18在顺序表的第几个位置int pos = findPosByValue(&L, 18);if (pos != -1){printf("值18在顺序表的第%d个位置\n", pos); //值18在顺序表的第1个位置}else{printf("查找失败!\n");}//测试完记得执行销毁操作,释放空间内存destroySeqList(&L);return 0;
}
10.完整代码
#include<stdio.h>
#include<stdlib.h>#define InitSize 50 //初始容量
#define Increment 10 //每次扩容的增量
typedef int ElemType;typedef struct SeqList {ElemType* data; //动态分配数组的指针int length; //顺序表当前的长度(元素个数)int capacity; //顺序表当前容量
}SeqList;// 操作1——初始化
void InitSeqList(SeqList* L) {L->data = (ElemType*)malloc(sizeof(ElemType) * InitSize);if (L->data == NULL){printf("内存分配失败!\n");exit(1); // 退出系统操作}L->length = 0;L->capacity = InitSize;
}// 增加顺序表的容量
void IncreaseCapacity(SeqList* L) {ElemType* newData = (ElemType*)realloc(L->data,(sizeof(ElemType)) * (InitSize + Increment));if (newData == NULL){printf("内存分配失败!\n");exit(1); // 退出系统操作}L->data = newData;L->capacity += Increment;
}//操作2——插入:在第pos个位置插入value值,即在数组下标pos-1的位置插入value值
int InsertSeqList(SeqList* L,int pos ,ElemType value) {//1.判断插入位置是否合法if (pos < 1 || pos > L->length + 1){printf("插入位置不合法!\n");return -1;}//2.判断顺序表存储空间是否满了if (L->length >= L->capacity){IncreaseCapacity(L); //空间不足,进行扩容操作}//3.将第pos个位置及往后的元素都后移一个位置,空出第pos个位置(这里采用逆序遍历)for(int i = L->length; i >= pos; i++){L->data[i] = L->data[i - 1];}//4.插入数据L->data[pos - 1] = value;//5.表长加1L->length++;return 0; //插入成功
}// 操作3——按位查找,即返回第pos个位置对应的value值
int findValueByPos(SeqList* L, int pos, ElemType* value) {//1.判断要查找的位置是否合理if (pos < 1 || pos > L->length){printf("查找位置不在当前顺序表范围内!\n");}//2.查找第pos个位置对应的value值*value = L->data[pos - 1];return 0; //查找成功
}// 操作4——按值查找,即返回value值对应的位序,即第几个,下标是位序减1
int findPosByValue(SeqList* L, ElemType value) {for (int i = 0; i < L->length ; i++){if (L->data[i] == value) {return i + 1;}}return -1; //未在该顺序表中找到该值
}// 操作5——删除:将第pos个的值赋值交给value变量存储后腾开第pos个位置
// 然后将第pos个后的数据都往前移动一个位置,填补第pos个位置
int deleteSeqList(SeqList* L, int pos,ElemType* value) {//1. 判断删除位置是否合理,即是否在存有数据的范围内if (pos < 1 || pos > L->length){printf("待删除位置不在合理范围内!\n");return -1; }//2. 判断空间是否为空if (L->length == 0){printf("当前空间未存有数据,无法完成删除操作!\n");}//3.将要被删除的数据赋值(转存于)value变量*value = L->data[pos - 1];//4.将第pos个位置往后的元素都往前挪一个位置for (int i = pos; i < L->length; i++){L->data[i - 1] = L->data[i];}//5.表长减1L->length--;return 0; //删除成功
}// 操作6——注销
void destroySeqList(SeqList* L) {if (L->data != NULL){free(L->data);L->data = NULL;L->length = 0;L->capacity = 0;}
}//操作7——打印顺序表中存放的数据
void printSeqList(SeqList* L) {if (L->length == 0){printf("当前顺序表为空!\n");}else {for (int i = 0; i < L->length ; i++){if (i == L->length - 1) {printf("%d", L->data[i]);}else{printf("%d ", L->data[i]);}}printf("\n");}printf("--------------------------------------------------\n");
}int main() {SeqList L;InitSeqList(&L);//插入数据测试if (InsertSeqList(&L,1,18) != 0){printf("插入失败!\n");}if (InsertSeqList(&L,2,7) != 0){printf("插入失败!\n");}if (InsertSeqList(&L,3,34) != 0){printf("插入失败!\n");}printSeqList(&L); // 18 7 34//删除数据测试ElemType value;if (deleteSeqList(&L, 2, &value) != 0){printf("删除失败!\n");}printSeqList(&L); // 18 34//按位查找测试,查找第1位的值是什么ElemType val;if (findValueByPos(&L,1,&val) == 0){printf("第1位的数据为:%d\n", val); //第1位的数据为:18}else{printf("查找失败!\n");}//按值查找测试,查找18在顺序表的第几个位置int pos = findPosByValue(&L, 18);if (pos != -1){printf("值18在顺序表的第%d个位置\n", pos); //值18在顺序表的第1个位置}else{printf("查找失败!\n");}//测试完记得执行销毁操作,释放空间内存destroySeqList(&L);return 0;
}
11.运行截图

如有问题,欢迎指出!
谢谢!
相关文章:
C语言_数据结构总结2:动态分配方式的顺序表
0——静态分配内存的顺序表和动态分配内存的顺序表的相同之处和不同之处 相同之处 基本操作逻辑相同:无论是静态分配还是动态分配的顺序表,其核心的操作逻辑是一致的。例如插入操作都需要将插入位置之后的元素依次后移,删除操作都需要将删除…...
嵌入式人工智能应用-第6章 人脸检测
嵌入式人工智能应用 人脸检测 嵌入式人工智能应用1 人脸检测1.1 CNN 介绍1.2 人脸检测原理1.3 MTCNN介绍1.4 NCNN介绍2 系统安装2.1 安装依赖库NCNN2.2 运行对应的库3 总结1 人脸检测 1.1 CNN 介绍 卷积神经网络。卷积是什么意思呢?从数学上说,卷积是一种运算。它是我们学习…...
关于无感方波启动预定位阶段
一、预定位的核心目标与原理 消除启动不确定性 无位置传感器下,转子初始位置未知,直接换相可能导致反转或失步。预定位通过施加固定方向磁场,强制转子对齐至预定角度(通常0或60电角度),建立初始位置基准。 …...
WSL安装及问题
1 概述 Windows Subsystem for Linux(简称WSL)是一个在Windows 10\11上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,开发人员可以在 Windows 计算机上同时访问 Windows 和…...
MySQL中的脏读与幻读:概念、影响与解决方案
在数据库事务处理中,脏读和幻读是两种常见的并发问题,可能导致数据不一致或逻辑错误。本文将结合实际场景,深入解析两者的原理及解决方案。 一、脏读(Dirty Read) 1. 概念解析 脏读指一个事务读取了另一个事务未提交…...
基于SpringBoot的商城管理系统(源码+部署教程)
运行环境 数据库:MySql 编译器:Intellij IDEA 前端运行环境:node.js v12.13.0 JAVA版本:JDK 1.8 主要功能 基于Springboot的商城管理系统包含管理端和用户端两个部分,主要功能有: 管理端 首页商品列…...
HeidiSQL:一款免费的数据库管理工具
HeidiSQL 是一款免费的图形化数据库管理工具,支持 MySQL、MariaDB、Microsoft SQL、PostgreSQL、SQLite、Interbase 以及 Firebird,目前只能在 Windows 平台使用。 HeidiSQL 的核心功能包括: 免费且开源,所有功能都可以直接使用。…...
Ae 效果详解:VR 色差
Ae菜单:效果/沉浸式视频/VR 色差 Immersive Video/VR Chromatic Aberrations VR 色差 VR Chromatic Aberrations效果用于模拟镜头色散现象,在 VR 视频中制造 RGB 通道错位的色彩偏移,以增强视觉风格或创造数字失真效果。 本效果适用于所有色深…...
计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Ubuntu 安装docker docker-compose
Docker 通过提供轻量级、可移植且高效的解决方案,简化了软件开发和部署。“docker build”命令是 Docker 镜像创建过程的核心。本文将探讨 Docker 构建命令、用法以及 Docker 构建的优化。 Docker 构建有什么作用? Docker build 是一个命令行界面 CLI命…...
【Linux内核系列】:深入解析输出以及输入重定向
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz ★★★ 本文前置知识: 文件系统以及文件系统调用接口 用c语言简单实现一个shell外壳程序 内容回顾 那么在此前的学习中,我们对于Linux的文件系统已经有了…...
【linux网络编程】端口
一、端口(Port)概述 在计算机网络中,端口(Port) 是用来标识不同进程或服务的逻辑通信端点。它类似于一座大楼的房间号,帮助操作系统和网络协议区分不同的应用程序,以便正确地传输数据。 1. 端口…...
PyTorch系列教程:Tensor.view() 方法详解
这篇简明扼要的文章是关于PyTorch中的tensor.view()方法的介绍与应用,与reshape()方法的区别,同时给出示例进行详细解释。 Tensor基础 Tensor(张量)的视图是一个新的Tensor,它与原始Tensor共享相同的底层数据,但具有不同的形状或…...
软件测试的基础入门(二)
文章目录 一、软件(开发)的生命周期什么是生命周期软件(开发)的生命周期需求分析计划设计编码测试运行维护 二、常见的开发模型瀑布模型流程优点缺点适应的场景 螺旋模型流程优点缺点适应的场景 增量模型和迭代模型流程适应的场景…...
Springboot + minio
参考: SpringBoot整合Minio_springboot minio-CSDN博客 <!--minio 依赖--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.11</version></dependency> applicaio…...
地下变电站如何实现安全智能运营-以110kV站为例看环境监测与设备联控
1、地下变电站简介 在经济发达的地区,由于城市中心土地资源紧张、征地拆迁费用昂贵,因此采用地下变电站来解决这些问题不失为一个好的途径和思路。地下变电站一般采用室内全封闭式组合电气设备,220&#x…...
windows无界面后台定时任务 (重启自启动,ODBS为例)
一、前言 mdb(Microsoft Database)是Microsoft Access中使用的一种数据存储格式,可以通过ODBC驱动程序进行访问和操作,在Python中也可以安装相应模块打开。 这是我在项目中更新bs数据的一个实践记录,结合windows定时一起记录一下,方便以后照搬~ 二、安装 Python安装库…...
FPGA 实验报告:四位全加器与三八译码器仿真实现
目录 安装Quartus软件 四位全加器 全加器、半加器 半加器: 全加器: 四位全加器电路图 创建项目 半加器 全加器 四位全加器 代码实现 半加器 全加器 四位全加器 三八译码器 创建项目 代码展示 modelsim仿真波形图 四位全加器 三八译码…...
win11 Visual Studio 17 2022源码编译 opencv4.11.0 + cuda12.6.3 启用GPU加速
win11 Visual Studio 17 2022 源码编译 opencv4.11.0 cuda12.6.3 启用GPU加速 配置: 生成 opencv 生成 opencv-python 1 下载源码和安装软件 win11 x64 系统 安装Visual Studio 17 2022 下载opencv4.11.0 源码 https://github.com/opencv/opencv/releases/tag/4.11.0 下载…...
Ribbon实现原理
文章目录 概要什么是Ribbon客户端负载均衡 RestTemplate核心方法GET 请求getForEntitygetForObject POST 请求postForEntitypostForObjectpostForLocation PUT请求DELETE请求 源码分析类图关系 与Eureka结合重试机制 概要 什么是Ribbon Spring Cloud Ribbon是一个基于HTTP和T…...
MuMu-LLaMA:通过大型语言模型进行多模态音乐理解和生成(Python代码实现+论文)
MuMu-LLaMA 模型是一种音乐理解和生成模型,能够进行音乐问答以及从文本、图像、视频和音频生成音乐,以及音乐编辑。该模型利用了用于音乐理解的 MERT、用于图像理解的 ViT 和用于视频理解的 ViViT 等编码器,以及作为音乐生成模型(…...
高效Android MQTT封装工具:简化物联网开发,提升性能与稳定性
在Android开发中,封装MQTT工具可以帮助简化与MQTT服务器的通信。MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,常用于物联网(IoT)设备之间的通信。 以下是一个简单的MQ…...
数据库原理7
1.“数据库系统运行与维护工具”的研究属于数据库管理系统软件 2.1970年IBM公司的高级研究员E.F.Codd提出了关系数据模型 3.每个属性的属性值是不可分解的,即关系的每个分量必须是一个不可分的数据项。属性值的取值应满足域完整性约束。 4.视图作用:简…...
2025最新比较使用的ai工具都有哪些,分别主要用于哪些方面?
文章目录 一、AI对话与交互工具二、AI写作与内容生成工具三、AI绘画与设计工具四、AI视频生成工具五、办公与效率工具六、其他实用工具选择建议 根据2025年最新行业动态和用户反馈,以下AI工具在多个领域表现突出,覆盖对话、写作、设计、视频生成等场景&a…...
什么是 MyBatis? 它的优点和缺点是什么?
一、 什么是 MyBatis? 定义: MyBatis 是一款优秀的持久层框架,用于简化 Java 应用程序与数据库之间的交互。MyBatis 通过 XML 或注解 的方式,将 SQL 语句与 Java 代码分离,提供了一种灵活的、易于维护的数据访问解决方…...
在ArcMap中通过Python编写自定义工具(Python Toolbox)实现点转线工具
文章目录 一、需求二、实现过程2.1、创建Python工具箱(.pyt)2.2、使用catalog测试代码2.3、在ArcMap中使用工具 三、测试 一、需求 通过插件的形式将点转线功能嵌入ArcMap界面,如何从零开始创建一个插件,包括按钮的添加、工具的实…...
Array and string offset access syntax with curly braces is deprecated
警告信息 “Array and string offset access syntax with curly braces is deprecated” 是 PHP 中的一个弃用警告(Deprecation Notice),表明在 PHP 中使用花括号 {} 来访问数组或字符串的偏移量已经被标记为过时。 背景 在 PHP 的早期版本…...
moodle 开源的在线学习管理系统(LMS)部署
一、Moodle 简介 Moodle(Modular Object-Oriented Dynamic Learning Environment)是一个开源的在线学习管理系统(LMS),广泛应用于教育机构和企业培训。其核心功能包括课程管理、作业提交、在线测试、论坛互动和成绩跟…...
后智能体时代的LLM和Agent
文章目录 1. 关于AI重塑的哲学体系2. 关于AI大模型体系的认知3. 关于AI大模型体系的畅想4. 关于人和AI大模型体系的共处5. 写在最后 随着OpenAI、Deepseek、Manus等等智能体的爆火,人们茶前饭后、插科打诨的话题都离不开这些智能体,现状也正如《人民日报…...
Day6 DFS
一、跳台阶 一个楼梯共有 nn 级台阶,每次可以走一级或者两级,问从第 00 级台阶走到第 nn 级台阶一共有多少种方案。 输入格式 共一行,包含一个整数 nn。 输出格式 共一行,包含一个整数,表示方案数。 数据范围 1…...
