数据结构-顺序表

文章目录

    • 线性表概念
    • 顺序表
      • 静态顺序表
      • 动态顺序表
    • 总结


线性表概念

线性表是最基本、最简单、也是最常用的一种数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…线性表(linear> list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
顺序表概念以及结构

![在这里插入图片描述](https://img-blog.csdnimg.cn/81fd4ce355c74003b39850991da432ee.png

顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。顺序表一般可以分为:
1.静态顺序表:使用定长数组存储。
2.动态顺序表:使用动态开辟的数组存储。

静态顺序表

概念:

静态顺序表就是给定存储数据的大小来存储数据,在运行时已经确定的了,一般都是通过一个固定大小的数组来储存元素

优点:

通过数组的下标就能够快速的找到相应的元素,有快速访问的效果

缺点

由于静态顺序表在开始时储存的空间大小已经确定了,无法改变,所以如果设置过大就会造成空间的浪费,如果太小就会造成数据溢出

实现:

1.我们通过静态的顺序表来实现增删
2.在实现我们的过程中每完成一个函数就验证一下,保证不会出错再实现下一个函数
3.我们要实现的函数有初始化、打印、判断数组空间是否已满、尾插、头插、尾删、头删

一.构建框架
1.通过多文件来链接
在这里插入图片描述
基本的头文件和创建的结构体和一些定义

#include<stdio.h>
#include<string.h>//用于初始化 memset函数
#include<stdlib.h>
#include <assert.h>//用assert函数-判断对错
#define  max 20   //方便改变数组的大小
typedef int SQDataType;//方便改变数据类型
struct SeqList     //创建结构体(由于结构体能放多种 不同的数据,
//我们这里就实现整数){SQDataType a[max];//数组int size;//记录元素个数};
typedef  struct SeqList  sl;//简化

二.分模块实现
1.初始化
我们将结构体中的数组和元素个数都初始化为0
代码实现:

void SeqListInit(sl* ps) {memset(ps->a, 0, sizeof(SQDataType) * max);//将数组内容初始化为0ps->size=0;//开始拥有0个元素
}

检查:
在这里插入图片描述

2.判断数组是否已经满了
我们通过比较size(数组中元素的个数)和(max数组最大 容量)来判断
代码实现:

int man(sl* ps) {if (ps->size >= max)//当size大于max时此时数组空间已经满了{return 0;}elsereturn 1;
}

3.尾插
因为数组是从下标0开始的,所以我们可以将插入的数据插到数组下标为size(元素的个数)那个位置即可,由于插入一个数据,所以size要加1
代码实现:

void  SeqListPushBack(sl* ps, SQDataType x) {//尾插assert(man(ps));//判断数组空间是否满了ps->a[ps->size] = x;//赋值ps->size++;//下标++}

检查:
我们这里插入 1,2,3,4
在这里插入图片描述

在这里插入图片描述
4.打印
通过循环将结构体中的数组内容打印出来
代码实现:

void SeqListPrint(sl* ps) {//打印for (int i = 0; i < ps->size; i++)printf("%d ", ps->a[i]);printf("\n");
}

检查:
在这里插入图片描述
5.头插
头插过程中我们要通过循环将所有数据都往后移动一位,再减插入的元素放到下标为0的位置即可,当然size也要加1哦
代码实现:

void SeqListPushFront(sl* ps, SQDataType x) {//头插assert(man(ps));for (int i =ps->size; i>0; i--) {//所有数据后移动一位ps->a[i] =ps->a[i-1] ;}ps->a[0] = x;ps->size++;
}

检查
我们在上面的基础上头插一个0
在这里插入图片描述

在这里插入图片描述
6.尾删
我们可以直接将数组最后一个赋为0(因为我们初始化本身就是0),当然size要减1
代码实现:

void SeqListPopBack(sl* ps) {//尾删ps->a[ps->size - 1] = 0;ps->size--;
}

检查:
在上面的基础上减去两个数
在这里插入图片描述

在这里插入图片描述
7.头删
我们可以直接通过循环直接将首元素直接覆盖
代码实现:

void SeqListPopFront(sl* ps) {//头删for (int i = 0; i < ps->size; i++)//所有数据前移动一位,将头个数据给覆盖掉ps->a[i] = ps->a[i + 1];ps->size--;//减少一个元素
}

检查:
在上面的基础上头删两个数据
在这里插入图片描述

在这里插入图片描述
所有代码一览:
SeqList.h:


```c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>//用于初始化 memset函数
#include<stdlib.h>
#include <assert.h>//用assert函数-判断对错
#define  max 20   //方便改变数组的大小
typedef int SQDataType;//方便改变数据类型
struct SeqList     //创建结构体{SQDataType a[max];int size;//记录元素个数};
typedef  struct SeqList  sl;//简化
// 增删查改等接口函数
void SeqListInit(sl* ps);//初始化
int man(sl* ps);//判断数组是否已满
void SeqListPrint(sl* ps);//打印
//   尾插  头插 尾删  头删
void SeqListPushBack(sl* ps, SQDataType x);//尾插
void SeqListPushFront(sl* ps, SQDataType x);//头插
void SeqListPopBack(sl* ps);//尾删
void SeqListPopFront(sl *ps);//头删

SeqList.c:

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void SeqListInit(sl* ps) {memset(ps->a, 0, sizeof(SQDataType) * max);//将数组内容初始化为0ps->size=0;//开始拥有0个元素
}
void SeqListPrint(sl* ps) {//打印for (int i = 0; i < ps->size; i++)printf("%d ", ps->a[i]);printf("\n");
}
int man(sl* ps) {if (ps->size >= max)//当size大于max时此时数组空间已经满了{return 0;}elsereturn 1;
}void  SeqListPushBack(sl* ps, SQDataType x) {//尾插assert(man(ps));//判断数组空间是否满了ps->a[ps->size] = x;//赋值ps->size++;//下标++}void SeqListPushFront(sl* ps, SQDataType x) {//头插assert(man(ps));for (int i =ps->size; i>0; i--) {//所有数据后移动一位ps->a[i] =ps->a[i-1] ;}ps->a[0] = x;ps->size++;
}
void SeqListPopBack(sl* ps) {//尾删ps->a[ps->size - 1] = 0;ps->size--;
}
void SeqListPopFront(sl* ps) {//头删for (int i = 0; i < ps->size; i++)//所有数据前移动一位,将头个数据给覆盖掉ps->a[i] = ps->a[i + 1];ps->size--;//减少一个元素
}

Test.c:

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void teat1() {sl s;SeqListInit(&s);SeqListPushBack(&s, 1);SeqListPushBack(&s, 2);SeqListPushBack(&s, 3);SeqListPushBack(&s, 4);SeqListPushFront(&s, 0);SeqListPopBack(&s);SeqListPopBack(&s);SeqListPopFront(&s);SeqListPopFront(&s);SeqListPrint(&s);
}
int main() {teat1();return 0;
}

以上就是静态顺序表的增删实现了

动态顺序表

概念

动态顺序表可以根据需求来扩容存储空间,比静态顺序表灵活,因此动态顺序表被广泛使用

优点:

可以根据需要动态地分配内存,灵活性更高。 可以避免静态数组可能出现的内存浪费问题。
由于内存空间是动态分配的,因此可以处理数据量不确定或者变化的情况

缺点:

由于插入、删除数据时可能会移动大量数据,所以效率较低

实现:
动态顺序表和静态的过程差不多,就是将数组的空间大小改为可变的
1.在顺序表的基础上增加了扩容函数,不需要判断空间是否满的函数,初始化函数也改变了
2.用指针的方式将数据链接起来
一.改变的创建的结构体

struct SeqList {SQDataType* a;//用指针的方式将数据链接起来int size;//元素的个数int capacity;//空间的大小
};

二.主要函数的实现
1.初始化:

void SeqListInit(sl* ps) {ps->a = NULL;//将指针置空ps->size = 0;//开始为0ps->capacity = 0;//空间开始为0
}

检查:
在这里插入图片描述
2.扩容:

void SeqListCheckCapacity(sl* ps) {if (ps->size == ps->capacity) {//判断空间是否满了,满了就扩容int ws = ps->capacity == 0 ? 4 : 2 * ps->capacity;//如果空间为0就先给4不然就给2倍SQDataType* tmp = (SQDataType*)realloc(ps->a, sizeof(SQDataType) * ws);//扩容,将首地址给tmpif (tmp == NULL)//判断是否成功扩容{printf("realloc fail\n");exit(-1);}else{ps->a = tmp;//将首地址给aps->capacity = ws;//将扩容后的空间大小赋给capacity}}
}

3.尾插
因为数组是从下标0开始的,所以我们可以将插入的数据插到数组下标为size(元素的个数)那个位置即可,由于插入一个数据,所以size要加1
代码实现:

void  SeqListPushBack(sl* ps, SQDataType x) {//尾插SeqListCheckCapacity(ps);//判断是否要扩容ps->a[ps->size] = x;//赋值ps->size++;//下标++}

检查:
我们这里插入 1,2,3,4
在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/dc0edc5f9ed444249653ea0805c7403a.png

4.打印与静态顺序表一样
5.头插
头插过程中我们要通过循环将所有数据都往后移动一位,再减插入的元素放到下标为0的位置即可,当然size也要加1哦
代码实现:

void SeqListPushFront(sl* ps, SQDataType x) {//头插SeqListCheckCapacity(ps);for (int i =ps->size; i>0; i--) {//所有数据后移动一位ps->a[i] =ps->a[i-1] ;}ps->a[0] = x;ps->size++;
}

检查:
我们在上面的基础上头插一个0
在这里插入图片描述
在这里插入图片描述
6.由于尾删和头删没有涉及到扩容,所以和静态顺序表的一样

总结

1.还有查改等没写,有兴趣的可以去试试哦
2.顺序表虽然可以通过扩容来解决空间问题,但是每次以2倍的增长时,还是会造成一定的空间浪费,如:我扩了100个空间,我只用了10个。
3.就是顺序表在插入或者删除时,需要移动大量的数据,这样导致效率不高

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!

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

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

相关文章

蚂蚁庄园小课堂答题今日答案最新

蚂蚁庄园小课堂答题今日答案最新 温馨提醒&#xff1a;由于本文章会停留在一个固定的更新时间上&#xff0c;包含当前日期最新的支付宝蚂蚁庄园小课堂答题今日答案。如果您看到这篇文章已成为过去时&#xff0c;请按下面的方法进入查看天天保持更新的最新今日答案&#xff1b; …

Linux 网络通信

(一)套接字Socket概念 Socket 中文意思是“插座”&#xff0c;在 Linux 环境下&#xff0c;用于表示进程 x 间网络通信的特殊文件 类型。本质为内核借助缓冲区形成的伪文件。 既然是文件&#xff0c;那么理所当然的&#xff0c;我们可以使用文件描述符引用套接字。Linux 系统…

Windows11安装后跳过联网登录

Windows11安装后跳过联网登录 实验设备&#xff1a; VMware17Pro虚拟机中使用Windows11镜像安装Windows11操作系统&#xff0c;并且在虚拟机中测试跳过联网登录。 步骤 说明&#xff1a;物理卸载网卡&#xff08;在虚拟机上禁用网卡&#xff09;没用 思路&#xff1a; sh…

8.统一异常处理 + 统一记录日志

目录 1.统一异常处理 2.统一记录日志 1.统一异常处理 在 HomeController 类中添加请求方法&#xff08;服务器发生异常之后需要统一处理异常&#xff0c;记录日志&#xff0c;然后转到 500 页面&#xff0c;需要人工处理重定向到 500 页面&#xff0c;提前把 500 页面请求访问…

经典神经网络——AlexNet模型论文详解及代码复现

一、背景 AlexNet是在2012年由Alex Krizhevsky等人提出的&#xff0c;该网络在2012年的ImageNet大赛上夺得了冠军&#xff0c;并且错误率比第二名高了很多。Alexnet共有8层结构&#xff0c;前5层为卷积层&#xff0c;后三层为全连接层。 论文地址&#xff1a;ImageNet Classif…

ModuleNotFoundError: No module named ‘mdtex2html‘ module已经安装还是报错,怎么办?

用streamlit运行ChatGLM/basic_model/web_demo.py的时候&#xff0c;出现了module not found&#xff1a; ModuleNotFoundError: No module named mdtex2html Traceback: File "/home/haiyue/.local/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script…

【阿里云】图像识别 智能分类识别 增加网络控制功能点(三)

一、增加网络控制功能 实现需求TCP 心跳机制解决Soket异常断开问题 二、Linux内核提供了通过sysctl命令查看和配置TCP KeepAlive参数的方法。 查看当前系统的TCP KeepAlive参数修改TCP KeepAlive参数 三、C语言实现TCP KeepAlive功能 四、setsockopt用于设置套接字选项的系…

Qt4利用MVC开发曲线数据编辑器

目录 1 需求 2 开发流程 1 搭建框架 2 构造函数 3 打开工程 4 实现应用程序参数加载 5 QCustomPlot和TableView的联动 6 数据的可视化修改 7 列表点击事件事先键盘控制 8 表格实现复制&#xff0c;粘贴&#xff0c;删除等一系列功能 9 曲线实现自适应范围和统一范围…

【JMeter】运行方式

第一种&#xff1a; 使用GUI 操作&#xff1a; 在JMeter界面菜单导航上点击运行按钮 一般用作创建TestPlan和调试脚本增加java堆空间来满足测试环境 第二种&#xff1a;使用CLI(Command Line) 性能测试一般请求量比较大&#xff0c;为了节省资源 CLI参数用法&#xff1a; 字段…

Flask Echarts 实现历史图形查询

Flask前后端数据动态交互涉及用户界面与服务器之间的灵活数据传递。用户界面使用ECharts图形库实时渲染数据。它提供了丰富多彩、交互性强的图表和地图&#xff0c;能够在网页上直观、生动地展示数据。ECharts支持各种常见的图表类型&#xff0c;包括折线图、柱状图、饼图、散点…

[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效

文章目录 Spring 如何解决循环依赖问题resource 与 autowire 同时存在时谁生效 Spring 如何解决循环依赖问题 Spring在实例化一个bean的时候&#xff0c;是首先递归实例化其所依赖的所有bean&#xff0c;直到某个bean没有依赖其他bean&#xff0c;此时就会将该实例返回&#x…

【JavaWeb】Servlet

Servlet 文章目录 Servlet一、简介二、开发流程三、生命周期四、ServletConfig和ServletContext五、HttpServletRequest常见API六、HttpServletResponse常见API七、请求转发和响应重定向7.1 概述7.2 请求转发7.3 响应重定向 八、请求与响应乱码问题8.1 GET与POST请求乱码8.2 响…

内网穿透的应用-Jupyter Notbook+cpolar内网穿透实现公共互联网访问使用数据分析工作

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…

五、Lua流程控制与函数

一、流程控制 &#xff08;一&#xff09;含义 Lua 编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码&#xff0c;在条件为 false 时执行其他指定代码。 &#xff08;二&#xff09;原型 if (成立) then执行体1else执行体2 end…

字符串入门算法题!

概述 字符串和数组一样算是比较简单的题目&#xff0c;正适合打算法基础&#xff0c;一定要认真对待&#xff01;&#xff01;&#xff01; 字符串类型的算法问题可以分为简单、中等和困难的难度级别&#xff0c;基础类型一些基本的字符串处理问题&#xff0c;如字符串的拼接…

自动化部署 扩容openGauss —— Ansible for openGauss

前言 大家好&#xff0c;今天我们为大家推荐一套基于Ansible开发的&#xff0c;自动化部署及扩容openGauss的脚本工具&#xff1a;Ansible for openGauss&#xff08;以下简称 AFO&#xff09;。 通过AFO&#xff0c;我们只需简单修改一些配置文件&#xff0c;即可快速部署多种…

数智赋能 锦江汽车携手苏州金龙打造高质量盛会服务

作为一家老牌客运公司&#xff0c;成立于1956年的上海锦江汽车服务有限公司&#xff08;以下简称锦江汽车&#xff09;&#xff0c;拥有1200多辆大巴和5000多辆轿车&#xff0c;是上海乃至长三角地区规模最大的专业旅游客运公司。面对客运市场的持续萎缩&#xff0c;锦江汽车坚…

王道数据结构课后代码题p19 第14题请设计一个尽可能高效的算法,计算并输出所有可能的三元组(a,b,c) 中的最小距离。(c语言代码实现)

本题其实就是找a到c的最小值 有讲解p19 第14题 c语言实现王道数据结构课后代码题_哔哩哔哩_bilibili 下方有图&#xff1a; 本题代码如下 int abs(int a)//计算绝对值 {if (a < 0)return -a;elsereturn a; } int min(int a, int b, int c)//a是否为三个数中的最小值 {if …

基于xml配置的AOP

目录 xml方式AOP快速入门 xml方式AOP配置详解 xml方式AOP快速入门 xml方式配置AOP的步骤 导入AOP相关坐标 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></de…

二叉树题目:结点与其祖先之间的最大差值

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;结点与其祖先之间的最大差值 出处&#xff1a;1026. 结点与其祖先之间的最大差值 难度 5 级 题目描述 要求 给…