【C语言|数据结构】数据结构顺序表

目录

一、数据结构

1.1概念

1.2总结

1.3为什么需要数据结构?

二、顺序表

1.顺序表的概念及结构

1.1线性表

2.顺序表分类

2.1顺序表和数组的区别

2.2顺序表的分类

2.2.1静态顺序表

2.2.1.1概念

2.2.1.2缺陷

2.2.2动态顺序表

三、动态顺序表的实现

3.1新建项目

3.2 SeqList.h

3.3SeqList.c

3.3.1初始化

3.3.2销毁

3.3.3打印

3.3.4扩容

3.3.4.1扩容原则选择

3.3.4.2扩容代码呈现

3.3.5尾插

3.3.6头插

3.3.7尾删

3.3.8头删

3.3.9指定位置之前插入数据

3.3.10指定位置之前删除数据

3.3.11查找

3.3.12 SeqList.c


一、数据结构

1.1概念

  • 数据结构是计算机存储、组织数据的⽅式。
  • 数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么⽅式构成,以及数据元素之间呈现的结构。

1.2总结

  • 1)能够存储数据(如顺序表、链表等结构)
  • 2)存储的数据能够⽅便查找

1.3为什么需要数据结构?

  • 程序中如果不对数据进⾏管理,可能会导致数据丢失、操作数据困难、野指针等情况。 通过数据结构,能够有效将数据组织和管理在⼀起。按照我们的⽅式任意对数据进⾏增删改查等操作。
  • 最基础的数据结构:数组。
  • 【思考】有了数组,为什么还要学习其他的数据结构?
  • 假定数组有10个空间,已经使⽤了5个,向数组中插⼊数据步骤: 求数组的⻓度,求数组的有效数据个数,向下标为数据有效个数的位置插⼊数据(注意:这⾥是 否要判断数组是否满了,满了还能继续插⼊吗)..... 假设数据量⾮常庞⼤,频繁的获取数组有效数据个数会影响程序执⾏效率。
  • 结论:最基础的数据结构能够提供的操作已经不能完全满⾜复杂算法实现。

二、顺序表

1.顺序表的概念及结构

1.1线性表
  • 线性表(linear list)是n个具有相同特性的数据元素的有限序列。
  • 线性表是⼀种在实际中⼴泛使 ⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串..
  •  线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.顺序表分类

2.1顺序表和数组的区别
  • 顺序表的底层结构是数组,对数组的封装,实现了常⽤的增删改查等接⼝
2.2顺序表的分类
2.2.1静态顺序表
2.2.1.1概念
  • 使⽤定⻓数组存储元素
2.2.1.2缺陷
  • 空间给少了不够⽤,给多了造成空间浪费

2.2.2动态顺序表

三、动态顺序表的实现

3.1新建项目

3.2 SeqList.h

//C语言
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLDataType;//不仅限于int类型 便于后续替换//动态顺序表
typedef struct SeqList
{SLDataType* arr;   //存储数据的底层结构int capacity;      //记录顺序表的空间大小int size;          //记录顺便当前有效的数据个数}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);//尾插/尾删/头插/头删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);

3.3SeqList.c

3.3.1初始化

void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = 0;ps->size = 0;}

3.3.2销毁


void SLDestroy(SL* ps)
{free(ps->arr);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}

3.3.3打印

void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}

3.3.4扩容

3.3.4.1扩容原则选择
  • 一次扩充一个空间:插入一个元素还不会造成空间浪费 ✖ 程序执行效率低下
  • 一次扩充固定个大小的空间(10、100)✖ 小了:造成频繁扩容,会造成程序运行低下;大了:造成空间浪费
  • 成倍数的扩增(1.5倍、2倍)✅相对高效:数据插入的越多,扩容的大小越来越大即插入数据的数量与扩容大小成近似真相关
3.3.4.2扩容代码呈现
  1. 首先判断动态数组的元素个数(size)是否等于容量(capacity)。
  2. 若相等,则需要进行扩容操作。
  3. 计算新的容量大小,如果原容量为0,则新容量为4,否则新容量为原容量的两倍。
  4. 调用realloc函数重新分配内存空间,将原动态数组的元素拷贝到新的内存空间中。
  5. 如果内存分配失败(temp为NULL),则输出错误信息并退出程序。
  6. 如果内存分配成功,则将新的内存空间地址赋值给动态数组指针arr,同时更新容量为新的容量大小。
//扩容
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* temp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (temp == NULL){perror("realloc fail!");//扩容失败exit(1);//退出}//扩容成功ps->arr = temp;ps->capacity = newCapacity;}}

3.3.5尾插

//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//断言,确保不为空//空间不够直接插入SLCheckCapacity(ps);//空间足够直接插入ps->arr[ps->size] = x;ps->size++;
}

3.3.6头插


//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//旧数据挪动for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;}

3.3.7尾删

//尾删
void SLPopBack(SL* ps)
{//顺序表为空assert(ps);assert(ps->size);//顺序表不为空ps->size--;
}

3.3.8头删

//头删
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--;
}

3.3.9指定位置之前插入数据

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->arr);SLCheckCapacity(ps);//pos及之后的数据挪动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;}

3.3.10指定位置之前删除数据

void SLErase(SL* ps, int pos)
{assert(ps);assert(ps >= 0 && pos < ps->size);for (int i = pos;i < ps->size;i++){ps->arr[i] = ps->arr[i + 1];}
}

3.3.11查找

int SLFind(SL* ps, SLDataType x)
{for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1; // 表示未找到
}

3.3.12 SeqList.c

#include"SeqList.h"//初始化和销毁
void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = 0;ps->size = 0;}void SLDestroy(SL* ps)
{free(ps->arr);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}//打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}//扩容
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* temp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (temp == NULL){perror("realloc fail!");//扩容失败exit(1);//退出}//扩容成功ps->arr = temp;ps->capacity = newCapacity;}}//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//断言,确保不为空//空间不够直接插入SLCheckCapacity(ps);//空间足够直接插入ps->arr[ps->size] = x;ps->size++;
}//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//旧数据挪动for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;}
//尾删
void SLPopBack(SL* ps)
{//顺序表为空assert(ps);assert(ps->size);//顺序表不为空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 SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->arr);SLCheckCapacity(ps);//pos及之后的数据挪动一位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(ps >= 0 && pos < ps->size);for (int i = pos;i < ps->size;i++){ps->arr[i] = ps->arr[i + 1];}
}int SLFind(SL* ps, SLDataType x)
{for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1; // 表示未找到
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

macbook电脑如何永久删除app软件?

在使用MacBook的过程中&#xff0c;我们经常会下载各种App来满足日常的工作和娱乐需求。然而&#xff0c;随着时间的积累&#xff0c;这些App不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢电脑的运行速度。那么&#xff0c;如何有效地管理和删除这些不再需要的App呢&#xf…

LeetCode 200:岛屿数量(图的简化版之网格结构上的BFS、DFS)

图的BFS和DFS 首先让我们回顾一下图的BFS和DFS遍历。可以看到这种BFS和DFS板子适用于图形状&#xff0c;或者说结构已经确定&#xff0c;即我们遍历的时候只需要从根节点从上往下遍历即可&#xff0c;不用考虑这个节点有几个叶子节点&#xff0c;是否会遍历到空节点等边界情况…

打印文件pdf怎么转换成word文档?pdf转换工具推荐

有时候我们可能需要重用PDF文件中的文本内容&#xff0c;比如引用某些段落、复制粘贴特定文字或提取数据&#xff0c;通过将pdf文件转换成word&#xff0c;可以轻松地提取和重用其中的文本&#xff0c;节省时间和努力&#xff0c;那么pdf怎么转word呢&#xff1f;可以试试本文推…

Day4.

单链表 #include <head.h>typedef struct List{int value;struct List *pointe; }*list; list create_space() {list s(struct List *)malloc(sizeof(struct List)); //向堆区申请空间s->pointe NULL;//初始化s->value 0;return s; } list inserhead_list(lis…

STM32 定时器

目录 TIM 定时器定时中断 定时器外部时钟 PWM驱动LED呼吸灯&#xff08;OC&#xff09; PWM控制舵机 PWMA驱动直流电机 输入捕获模式测频率&#xff08;IC&#xff09; 输入捕获模式测占空比 编码器接口测速(编码器接口) TIM 通用定时器 高级定时器 定时器定时中断 Ti…

C#静态数组删除数组元素不改变数组长度 vs 动态数组删除数组元素改变数组长度

目录 一、使用的方法 1.对静态数组删除指定长度并不改变数长度的方法 &#xff08;1&#xff09;静态数组 &#xff08;2&#xff09;对静态数组删除元素不得改变其长度 2.对动态数组删除指定长度并改变数长度的方法 &#xff08;1&#xff09;动态数组 &#xff08;2&a…

vite项目配置根据不同的打包环境使用不同的请求路径VITE_BASE_URL,包括报错解决

vite环境配置可以看官方文档&#xff1a;环境变量和模式 | Vite 官方中文文档 创建环境配置文件 在项目根目录下面创建.env和.env.production文件&#xff0c;.env是开发环境使用的&#xff0c;.env.production是生产环境使用的。 .env文件&#xff1a; # 基本环境 VITE_APP…

[机缘参悟-154] :一个软件架构师对佛学的理解 -19- 宏大的佛教世界观、宇宙观,即系统架构:三千大千世界、佛土、三界、九地、二十五有、六道轮回

目录 一、什么是世界观 二、佛教的世界观 2.1 佛教的世界观的关注点 2.2 佛教世界观的核心要义 2.3 佛教的世界观 三、佛教的宇宙观&#xff1a;三千大千世界 3.1 佛教的宇宙观 3.2 三千大千世界 四、三界、九地、二十五有、六道 4.1 三界与三界之外 4.1.1 关于三界…

人工智能福利站,初识人工智能,图神经网络学习,第四课

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先&#xff0c;WebSocket和HTTP是两种不同的协议&#xff0c;它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别&#xff1a; HTTP (HyperText Transfer Protocol): 请求-响应模型&#xff1a; HTTP 是基于请求-响应模型的协…

夜天之书 #95 GreptimeDB 社群观察报告

GreptimeDB 是格睿科技&#xff08;Greptime&#xff09;公司研发的一款开源时序数据库&#xff0c;其源代码[1]在 GitHub 平台公开发布。 https://github.com/GreptimeTeam/greptimedb 我从 2022 年开始知道有 GreptimeDB 这个项目。2023 年&#xff0c;我注意到他们的 Commun…

字节3面真题,LeetCode上hard难度,极具启发性题解

文章目录 &#x1f680;前言&#x1f680;LeetCode&#xff1a;41. 缺失的第一个正整数&#x1f680;思路&#x1f680;整个代码思路串一下&#x1f680;Code &#x1f680;前言 铁子们好啊&#xff01;阿辉来讲道题&#xff0c;这道题据说是23年字节3面真题&#xff0c;LeetC…

OpenShift AI - 运行欺诈检测模型和流程

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.14 RHODS 2.50 的环境中验证 文章目录 准备运行环境安装 OpenShift AI 环境安装 Minio 对象存储软件创建 Data Science Project创建 Data connection创建 Workbench配置 Model server创建 …

解决“org.apache.catalina.startup.Catalina.stopServer 未配置关闭端口。通过OS信号关闭服务器。服务器未关闭“

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 问题描述 项目部署至Tomcat服务器报错&#xff1a;org.apache.catalina.startup.Catalina.stopServer 未配置关闭端口。通过OS信号关闭服务 器。服务器未关闭&#xff1b;图…

探讨CSDN等级制度:博客等级、原力等级、创作者等级

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

学习笔记——ENM模拟

学习笔记——ENM模拟 文章目录 前言一、文献一1. 材料与方法1.1. 大致概念1.2. 生态模型的构建1.2.1. 数据来源&#xff1a;1.2.2. 数据处理&#xff1a;1.2.3. 模型参数优化&#xff1a; 1.3. 适生情况预测1.3.1. 预测模型构建1.3.2. 适生区划分 1.4. 模型的评估与验证 2. 结果…

吉他学习:识谱,认识节奏,视唱节奏,节拍器的使用

第九课 识谱https://m.lizhiweike.com/lecture2/29362692 第十课 基础乐理&#xff08;二&#xff09;——节奏篇https://mp.csdn.net/mp_blog/creation/editor?spm1011.2124.3001.6192 第十一课 视唱节奏&#xff08;一&#xff09;https://m.lizhiweike.com/lecture2/293634…

【大模型上下文长度扩展】LongQLoRA:单GPU(V100)环境下的语言模型优化方案

LongQLoRA 核心问题子问题1: 预定义的上下文长度限制子问题2: 训练资源的需求高子问题3: 保持模型性能分析不足 LongQLoRA方法拆解子问题1: 上下文长度限制子问题2: 高GPU内存需求子问题3: 精确量化导致的性能损失分析不足效果 论文&#xff1a;https://arxiv.org/pdf/2311.048…

使用深度学习对视频进行分类

目录 加载预训练卷积网络 加载数据 将帧转换为特征向量 准备训练数据 创建 LSTM 网络 指定训练选项 训练 LSTM 网络 组合视频分类网络 使用新数据进行分类 辅助函数 此示例说明如何通过将预训练图像分类模型和 LSTM 网络相结合来创建视频分类网络。 要为视频…