C语言_数据结构总结2:动态分配方式的顺序表

0——静态分配内存的顺序表和动态分配内存的顺序表的相同之处和不同之处

相同之处
  • 基本操作逻辑相同:无论是静态分配还是动态分配的顺序表,其核心的操作逻辑是一致的。例如插入操作都需要将插入位置之后的元素依次后移,删除操作都需要将删除位置之后的元素依次前移,查找操作也都是通过遍历或者直接定位来完成。

  • 数据元素存储方式相同:两种顺序表都是将数据元素依次存储在连续的内存空间中,都可以通过数组下标来直接访问元素,时间复杂度为 \(O(1)\)。

  • 功能用途相同:都用于实现线性表的功能,支持数据的插入、删除、查找等基本操作。

不同之处
  • 内存分配方式

    • 静态分配:在编译时就确定了顺序表的最大容量,使用数组来存储元素,数组的大小在程序运行过程中不能改变。

    • 动态分配:在程序运行时根据需要动态地分配内存空间,可以通过 mallocrealloc 等函数来调整顺序表的容量。

  • 内存管理

    • 静态分配:不需要手动管理内存,数组的内存空间由系统自动分配和释放。

    • 动态分配:需要手动管理内存,使用 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.运行截图

如有问题,欢迎指出!

谢谢!

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

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

相关文章

Vue 与 Element UI 深度探秘:从 Array.isArray 到动态绑定的技术之旅!✨

以下是一篇深入的技术博客&#xff0c;基于我们对 compare-form.vue 和 <w-form-select.vue> 的所有讨论&#xff0c;涵盖 Array.isArray、option-label/option-value、:list 动态绑定、: 语法以及 Vue 2/3 兼容性等问题。博客风格轻松有趣&#xff0c;加入 SVG 图解和实…

计算机视觉|3D卷积网络VoxelNet:点云检测的革新力量

一、引言 在科技快速发展的背景下&#xff0c;3D 目标检测技术在自动驾驶和机器人领域中具有重要作用。 在自动驾驶领域&#xff0c;车辆需实时、准确感知周围环境中的目标物体&#xff0c;如行人、车辆、交通标志和障碍物等。只有精确检测这些目标的位置、姿态和类别&#x…

前端打包优化相关 Webpack

前端打包优化相关 Webpack 打包时间的优化&#xff08;基于 Vue CLI 4 Webpack 5&#xff09; 1. Webpack 配置减少打包时间 1.1 对 JS 配置&#xff1a;排除 node_modules 和 src 中的打包内容 在开发环境下&#xff0c;修改 Webpack 的 JS 规则&#xff0c;排除 /node_m…

leetcode69.x 的平方根

题目&#xff1a; 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和算符&#xff0c;例如 pow(x, 0.5) 或者 x ** 0.5 。…

Docker 部署 MongoDB 并持久化数据

Docker 部署 MongoDB 并持久化数据 在现代开发中&#xff0c;MongoDB 作为 NoSQL 数据库广泛应用&#xff0c;而 Docker 则提供了高效的容器化方案。本教程将介绍如何使用 Docker 快速部署 MongoDB&#xff0c;并实现数据持久化&#xff0c;确保数据不会因容器重启或删除而丢失…

信奥赛CSP-J复赛集训(模拟算法专题)(3):P1089 [NOIP 2004 提高组] 津津的储蓄计划

信奥赛CSP-J复赛集训&#xff08;模拟算法专题&#xff09;&#xff08;3&#xff09;&#xff1a;P1089 [NOIP 2004 提高组] 津津的储蓄计划 题目描述 津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300 300 300 元钱&#xff0c;津津会预算这个月的花销&#xff0…

日新F1、瑞研F600P 干线光纤熔接(熔接损耗最大0.03DB)

Ⅰ. 设备特性对比与实测验证 1. 日新F1&#xff08;两马达&#xff09;极限参数 切割角度&#xff1a;必须≤0.3&#xff08;双边累计误差&#xff1c;0.6&#xff09; ▶ 实测案例&#xff1a;切割0.35时&#xff0c;损耗波动达0.05-0.08dB&#xff08;超干线标准&#xff09…

【量化科普】Sharpe Ratio,夏普比率

【量化科普】Sharpe Ratio&#xff0c;夏普比率 &#x1f680;量化软件开通 &#x1f680;量化实战教程 在量化投资领域&#xff0c;夏普比率&#xff08;Sharpe Ratio&#xff09;是一个非常重要的风险调整后收益指标。它由诺贝尔经济学奖得主威廉F夏普&#xff08;William…

数据结构--【顺序表与链表】笔记

顺序表 template <class T> class arrList :public List<T> //表示 arrList 类以公有继承的方式继承自 List<T> 类 //公有继承意味着 List<T> 类的公共成员在 arrList 类中仍然是公共成员&#xff0c;受保护成员在 arrList 类中仍然是受保护成员。 { …

idea中隐藏目录

可能的解决步骤&#xff1a; 排除目录的方法是否在2021版本中有变化&#xff1f;应该没有&#xff0c;还是通过右键标记为排除。 用户可能想完全隐藏目录&#xff0c;比如在项目视图中不显示&#xff0c;这可能需要调整项目视图的设置&#xff0c;比如取消勾选“显示排除的文件…

AWS 如何导入内部SSL 证书

SSL 证书的很重要的功能就是 HTTP- > HTTPS, 下面就说明一下怎么导入ssl 证书,然后绑定证书到ALB. 以下示例说明如何使用 AWS Management Console 导入证书。 从以下位置打开 ACM 控制台:https://console.aws.amazon.com/acm/home。如果您是首次使用 ACM,请查找 AWS Cer…

2025最新群智能优化算法:基于RRT的优化器(RRT-based Optimizer,RRTO)求解23个经典函数测试集,MATLAB

一、基于RRT的优化器 基于RRT的优化器&#xff08;RRT-based Optimizer&#xff0c;RRTO&#xff09;是2025年提出的一种新型元启发式算法。其受常用于机器人路径规划的快速探索随机树&#xff08;RRT&#xff09;算法的搜索机制启发&#xff0c;首次将RRT算法的概念与元启发式…

doris: Oracle

Apache Doris JDBC Catalog 支持通过标准 JDBC 接口连接 Oracle 数据库。本文档介绍如何配置 Oracle 数据库连接。 使用须知​ 要连接到 Oracle 数据库&#xff0c;您需要 Oracle 19c, 18c, 12c, 11g 或 10g。 Oracle 数据库的 JDBC 驱动程序&#xff0c;您可以从 Maven 仓库…

im即时聊天客服系统SaaS还是私有化部署:成本、安全与定制化的权衡策略

随着即时通讯技术的不断发展&#xff0c;IM即时聊天客服系统已经成为企业与客户沟通、解决问题、提升用户体验的重要工具。在选择IM即时聊天客服系统时&#xff0c;企业面临一个重要决策&#xff1a;选择SaaS&#xff08;软件即服务&#xff09;解决方案&#xff0c;还是进行私…

mysql中in和exists的区别?

大家好&#xff0c;我是锋哥。今天分享关于【mysql中in和exists的区别?】面试题。希望对大家有帮助&#xff1b; mysql中in和exists的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MySQL 中&#xff0c;IN 和 EXISTS 都用于进行子查询&#xff0c;但它…

element-plus中table组件的使用

1、table组件的基本使用 注意&#xff1a; ①对象集合&#xff0c;要从后端查询。 ②prop是集合中的对象的属性名&#xff1b;label是表格表头的名称。 2、将性别一列的71转为男&#xff0c;72转为女 问题描述&#xff1a; 解决步骤&#xff1a; ①将el-table-column变成双标签…

Django小白级开发入门

1、Django概述 Django是一个开放源代码的Web应用框架&#xff0c;由Python写成。采用了MTV的框架模式&#xff0c;即模型M&#xff0c;视图V和模版T。 Django 框架的核心组件有&#xff1a; 用于创建模型的对象关系映射为最终用户设计较好的管理界面URL 设计设计者友好的模板…

使用 display: flex 实现动态布局:每行两个 item,单数时最后一个占满整行

文章目录 使用 display: flex 实现动态布局&#xff1a;每行两个 item&#xff0c;单数时最后一个占满整行 &#x1f3af;一、需求分析二、实现思路三、代码实现1. HTML 结构2. CSS 样式关键点解析&#xff1a; 四、效果演示HTML 示例&#xff1a;效果&#xff1a; 五、完整代码…

preloaded-classes裁剪

系统预加载了哪些class类&#xff1f;system/etc/preloaded-classes 修改源代码&#xff1f; frameworks\base\config\preloaded-classes 默认位置&#xff0c;如果改了不生效&#xff0c;可能有其它模块的mk文件指定了preloaded-classes覆盖了framework模块&#xff0c;例如…

华为配置篇-OSPF基础实验

OSPF 一、简述二、常用命令总结三、实验3.1 OSPF单区域3.2 OSPF多区域3.3 OSPF 的邻接关系和 LSA 置底 一、简述 OSPF&#xff08;开放式最短路径优先协议&#xff09; 基本定义 全称&#xff1a;Open Shortest Path First 类型&#xff1a;链路状态路由协议&#xff08;IGP&…