当前位置: 首页 > news >正文

史上最详细的改良顺序表讲解,看完不会你打我

目录

0.什么是顺序表

1.顺序表里结构体的定义

2.顺序表的初始化

3.顺序表的输入

4.增加顺序表的长度

5.1顺序表的元素查找(按位查找)

5.2顺序表的元素查找(按值查找)在顺序表进行按值查找,大概只能通过遍历的方式,这也算是顺序表的缺点吧!

6.顺序表的元素插入

7.顺序表的元素删除

8.顺序表的打印

9.求顺序表的表长

10.顺序表的销毁

11.运行结果 

 12.全部代码

0.什么是顺序表

  • 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组
    上完成数据的增删查改。

  • 顺序表:可动态增长的数组,要求数据是连续存储的

1.顺序表里结构体的定义

typedef struct SList
{int length;int MaxSize;int* data;
}SList;

length为当前顺序表长度 MaxSize是顺序表最大长度 ,* data是定义顺序表中元素类型的数组指针

2.顺序表的初始化

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#define InitSize 10void InitSList(SList& L)
{L.data = (int*)malloc(sizeof(int) * InitSize);if (L.data == NULL){printf("%s\n",strerror(errno));}L.length = 0;L.MaxSize = InitSize;
}

需要注意的是,malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。在使用malloc函数开辟的空间中,不能进行指针的移动,因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配。

我们使用malloc函数申请大小为InitSize个字节的空间,成功申请会返回指向所申请空间的指针,如果申请失败会返回空指针NULL。

可能会空间开辟失败的情况,我们加上strerror函数。

strerror函数会返回错误码所对应的错误信息,返回值是一个指向描述错误的字符串的指针。

要使用它的话,必须包含errno.h这个头文件。

  • 每一个这样的错误码都对应着一个错误信息,sterror函数能把错误码所对应错误信息的首字符的地址返回。
  • 当C语言的库函数调用失败的时候,会将一个错误码存放在一个叫errno的变量中。
  • 当我们想知道调用库函数的时候发生了什么错误信息,就可以将errno中的错误码翻译成错误信息。

如图,当我们所要的空间太大,初始化失败时

 它会提示空间不够。

3.顺序表的输入

void WriteSList(SList& L)
{printf("请输入你要创建的顺序表的长度:>");scanf("%d", &L.length);printf("请输入你要创建的顺序表的元素:>");for (int j = 0; j < L.length; j++){scanf("%d", &L.data[j]);}
}

这一部分没有什么好说的,我们先输入长度再将每个元素输入就行。

4.增加顺序表的长度

我们定义一个*p指针来指向原顺序表的地址,之后再使用malloc函数来开辟一块更大的空间,空间大小由我们来定义,再将*p指向的值,也就是原顺序表的内容挨个赋值给新的顺序表,最后将原来的空间删除即可。不要忘记让p指向空指针哦!

void IncreaseSize(SList& L)
{int len;int* p = L.data;printf("请输入你要增加的长度:>");scanf("%d", &len);L.data = (int*)malloc(sizeof(int) * (L.MaxSize+len));for (int i = 0; i < L.length; i++){L.data[i] = p[i];}L.MaxSize = L.MaxSize + len;free(p);p=NULL;
}

5.1顺序表的元素查找(按位查找)

按位查找直接通过数组下标即可。 

bool GetElem(SList& L)
{int i;printf("你要找第几个元素:>");scanf("%d", &i);if (i<1 || i>L.length){return false;}printf("第%d个元素是%d\n", i, L.data[i - 1]);return true;
}

布尔型(bool)变量的值只有 真 (true) 和假 (false)。一般将非零值看做true,将零值看做false。使用布尔型可以增加代码的可读性。

5.2顺序表的元素查找(按值查找)
在顺序表进行按值查找,大概只能通过遍历的方式,这也算是顺序表的缺点吧!

顺序表按值查找的时间复杂度为:O(n),效率比较低。

void LocateElem(SList& L)
{int e, i, k=1;printf("请输入你要查找的元素:>");scanf("%d", &e);for (i = 0; i < L.length; i++){if (e == L.data[i]){k = 0;	printf("找到了,是第%d个元素\n", i + 1);break;}}if (k){printf("找不到该元素\n");}
}

6.顺序表的元素插入

将顺序表元素的插入类比成为我们排队,当有一个人想要插入一个中间的位置时,后面的人一定会因为插队的人而后移一位。倒数第二个人会到原先倒数第一人的位置,而原先倒数第一的那个人会后移一位,所以最后表长会加一。

需要判断的有两点:

1.顺序表的空间是否够用。

2.所插入的位置是否合法,有没有越界。

bool InsertSList(SList& L)
{int i, e;printf("请输入要插入的位置和元素:>");scanf("%d%d", &i, &e);if (i<1 || i>L.length){return false;}if (L.length > L.MaxSize){return false;}for (int j = L.length; j >= i; j--){L.data[j] = L.data[j - 1];}L.data[i - 1] = e;L.length++;printf("插入的元素是%d,插入的位置是%d\n", e, i);return true;
}

我们同样使用布尔型,在以上两种情况时返回一个false值。

让插入位置之后的元素挨个后移,在腾出的位置插入要插入的元素,返回一个true值。

7.顺序表的元素删除

依旧可以用排队的例子来说,队伍中有一个人有事要走,那么他的位置就会空出来,这时候他后面的人就要挨个向前一位来补齐这个位置。当然,最后表长会减一。

bool DeleteSList(SList& L)
{int i,j,e;printf("请输入你要删除的元素位置:>");scanf("%d", &i);if (i<1 || i>L.length){return false;}if (!L.data){return false;}e = L.data[i-1];for (j = i; j <= L.length;j++){L.data[j-1] = L.data[j];}L.length--;printf("删除的元素是%d,它的位置是%d\n",e, i);return true;
}

8.顺序表的打印

首先判断表是否为空表,是空表时返回一个false。

bool PrintSList(SList &L)
{if (!L.data){return false;}printf("数组里的元素有:>");for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");return true;
}

9.求顺序表的表长

int GetLength(SList& L)
{if (L.length == 0){return 0;}return L.length;
}

10.顺序表的销毁

getchar的使用是很关键的,用来接收前面的回车,如果不加的话之后的scanf将会直接被跳过。

就如上篇博客所说,malloc开辟的空间是在堆区的,这片空间需要程序员主动去释放,不然会导致内存泄露的问题。大家感兴趣可以看看上篇博客。

我眼中的‘C’——动态内存+柔型数组_陈大大陈的博客-CSDN博客 

void DestroySList(SList& L)
{char c;getchar();printf("是否销毁顺序表(Y/N):>");scanf("%s", &c);if (c == 'Y'){L.length = 0;L.MaxSize = 0;free(L.data);L.data=NULL;printf("顺序表已销毁\n");}
}

11.运行结果 

 12.全部代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#define InitSize 10
typedef struct SList
{int length;int MaxSize;int* data;
}SList;
void InitSList(SList& L)
{L.data = (int*)malloc(sizeof(int) * InitSize);if (L.data == NULL){perror("malloc");}L.length = 0;L.MaxSize = InitSize;
}
void WriteSList(SList& L)
{printf("请输入你要创建的顺序表的长度:>");scanf("%d", &L.length);printf("请输入你要创建的顺序表的元素:>");for (int j = 0; j < L.length; j++){scanf("%d", &L.data[j]);}
}
void IncreaseSize(SList& L)
{int len;int* p = L.data;printf("请输入你要增加的长度:>");scanf("%d", &len);L.data = (int*)malloc(sizeof(int) * (L.MaxSize+len));for (int i = 0; i < L.length; i++){L.data[i] = p[i];}L.MaxSize = L.MaxSize + len;free(p);p = NULL;
}
bool GetElem(SList& L)
{int i;printf("你要找第几个元素:>");scanf("%d", &i);if (i<1 || i>L.length){return false;}printf("第%d个元素是%d\n", i, L.data[i - 1]);return true;
}
void LocateElem(SList& L)
{int e, i, k=1;printf("请输入你要查找的元素:>");scanf("%d", &e);for (i = 0; i < L.length; i++){if (e == L.data[i]){k = 0;	printf("找到了,是第%d个元素\n", i + 1);break;}}if (k){printf("找不到该元素\n");}
}
bool InsertSList(SList& L)
{int i, e;printf("请输入要插入的位置和元素:>");scanf("%d%d", &i, &e);if (i<1 || i>L.length){return false;}if (L.length > L.MaxSize){return false;}for (int j = L.length; j >= i; j--){L.data[j] = L.data[j - 1];}L.data[i - 1] = e;L.length++;printf("插入的元素是%d,插入的位置是%d\n", e, i);return true;
}
bool DeleteSList(SList& L)
{int i,j,e;printf("请输入你要删除的元素位置:>");scanf("%d", &i);if (i<1 || i>L.length){return false;}if (!L.data){return false;}e = L.data[i-1];for (j = i; j <= L.length;j++){L.data[j-1] = L.data[j];}L.length--;printf("删除的元素是%d,它的位置是%d\n",e, i);return true;
}
bool PrintSList(SList &L)
{if (!L.data){return false;}printf("数组里的元素有:>");for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");return true;
}
int GetLength(SList& L)
{if (L.length == 0){return 0;}return L.length;
}
void DestroySList(SList& L)
{char c;getchar();printf("是否销毁顺序表(Y/N):>");scanf("%s", &c);if (c == 'Y'){L.length = 0;L.MaxSize = 0;free(L.data);L.data = NULL;printf("顺序表已销毁\n");}
}
int main()
{SList L;InitSList(L);WriteSList(L);PrintSList(L);IncreaseSize(L);InsertSList(L);PrintSList(L);DeleteSList(L);PrintSList(L);GetElem(L);LocateElem(L);int len = GetLength(L);printf("顺序表的长度是%d\n", len);DestroySList(L);return 0;
}

 这篇博客旨在总结我自己阶段性的学习,要是能帮助到大家,那可真是三生有幸!如果觉得我写的不错的话还请点个赞和关注哦~我会持续输出编程的知识的!😘😘😘

相关文章:

史上最详细的改良顺序表讲解,看完不会你打我

目录 0.什么是顺序表 1.顺序表里结构体的定义 2.顺序表的初始化 3.顺序表的输入 4.增加顺序表的长度 5.1顺序表的元素查找&#xff08;按位查找&#xff09; 5.2顺序表的元素查找&#xff08;按值查找&#xff09;在顺序表进行按值查找&#xff0c;大概只能通过遍历的方…...

【Unity入门】资源包导入和导出

【Unity入门】资源包导入和导出 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;1&#xff09;资源目录 Unity的资源&#xff08;模型&#xff0c;场景&#xff0c;脚本&#xff09;等都保存在Assert目录下&…...

python条件语句与循环语句

目录 一、条件语句 1.1if 二、循环语句 2.1while 2.2for循环 2.3break和continue 三、test和总结 一、条件语句 1.1if Python条件语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 Python程序语言指定&#xff1a; 任…...

【leetcode】链表(2)

目录 1. 环形链表 解题思路 2. 环形链表 II 解题思路 3. 删除排序链表中的重复元素 解题思路 4. 删除排序链表中的重复元素 II 解题思路 5. 移除链表元素 解题思路 6. 链表的中间结点 解题思路 1. 环形链表 OJ&#xff1a;环形链表 给你一个链表的头节点 head &am…...

使用Vue+vue-router+路由守卫实现路由鉴权功能实战

目录 一、本节介绍和上节回顾 1. 上节介绍 2. Vue SpringBoot前后端分离项目实战的目录 3. 本小节介绍 二、Vue-router改造以及路由鉴权 1. 路由数据的拆分 2. 路由守卫 三、404错误页的实现 1. 创建全局css样式 2. 全局样式引入 3. 404页面的开发 4. el-button的…...

多线程(三):Thread 类的基本属性

上一个篇章浅浅了解了一下 线程的概念&#xff0c;进程与线程的区别&#xff0c;如何实现多线程编程。 而且上一章提到一个重要的面试点&#xff1a; start 方法和 run 方法的区别。 start 方法是从系统那里创建一个新的线程&#xff0c;这个线程会自动调用内部的run 方法&…...

蓝桥杯嵌入式第六课--串口收发

前言串口作为一个考试中考察频率较高的考点&#xff0c;其套路比较固定&#xff0c;因此值得我们仔细把握。本节课主要着眼于快速配置实现 串口收发与串口的中断。CubeMX配置选择串口2配置异步收发模式基本参数设置&#xff08;波特率、校验位等等&#xff09;开启串口收发中断…...

蓝桥杯冲刺 - Lastweek - 你离省一仅剩一步之遥!!!(掌握【DP】冲刺国赛)

文章目录&#x1f4ac;前言&#x1f3af;week3&#x1f332;day10-1背包完全背包多重背包多重背包 II分组背包&#x1f332;day2数字三角形 - 线性DP1015. 摘花生 - 数字三角形&#x1f332;day3最长上升子序列 - 线性DP1017. 怪盗基德的滑翔翼 - LIS1014.登山 - LIS最长公共子…...

C++ map与set的学习

1. 关联式容器在初阶阶段&#xff0c;我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。关联式容器也…...

【C语言初阶】函数

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;函数是什么&#xff1f;&#x1f337;函数的分类&#x1f33a;库函数&#x1f33a;自定义函数&#x1f337;函数的参数&#x1f337;函数的调用&#x1f337;函数的嵌套调用和链式访问&#x1f33a;嵌套调用&a…...

CentOS 7安装redis6.2.6(包括服务开机自启和开放端口)

CentOS 7安装redis6.2.61. 官网下载redis文件2. 校验安装依赖2.1 安装系统默认版本gcc2.2 升级gcc版本3. 解压编译安装4. 修改配置redis.conf4.2 设置密码4.3 绑定ip&#xff08;可选&#xff09;5. 启动redis服务并测试5.2 测试安装是否成功5.3 redis开机自启配置6.开放防火墙…...

基于注解的自动装配~

Autowired&#xff1a;实现自动装配功能的注解 Autowired注解能够标识的位置&#xff1a; 标识在成员变量上&#xff0c;此时不需要设置成员变量的set方法标识在成员变量对应的set方法上标识在为当前成员变量赋值的有参构造上使用注解进行自动装配&#xff0c;只要在其成员变量…...

【深度学习】【分布式训练】Collective通信操作及Pytorch示例

相关博客 【深度学习】【分布式训练】Collective通信操作及Pytorch示例 【自然语言处理】【大模型】大语言模型BLOOM推理工具测试 【自然语言处理】【大模型】GLM-130B&#xff1a;一个开源双语预训练语言模型 【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介…...

Spring常用注解说明

目录 1.常用注解 2.特别说明 3.xml及注解方式 1.常用注解 (1) SpringBootApplication (2) ControllerRestControllerRequestMappingRequestParamPathVariableGetMappingPostMappingPutMappingDeleteMappingResponseBodyRequestBodyCrossOrigin (3) ConfigurationBeanServ…...

13-C++面向对象(纯虚函数(抽象类)、多继承、多继承-虚函数、菱形继承、虚继承、静态成员)

虚析构函数 存在父类指针指向子类对象的情况&#xff0c;应该将析构函数声明为虚函数&#xff08;虚析构函数&#xff09; 纯虚函数 纯虚函数&#xff1a;没有函数体且初始化为0的虚函数&#xff0c;用来定义接口规范 抽象类&#xff1a; 含有纯虚函数的类&#xff0c;不可以实…...

Android DataBinding 自定义View实现数据双向绑定

看不懂的可以先看看单向数据绑定&#xff1a;Android DataBinding数据变化时自动更新界面_皮皮高的博客-CSDN博客 然后再确定已经启动了dataBinding的情况下&#xff0c;按下面的顺序来&#xff1a; 首先创建一个自定义View&#xff1a; import android.content.Context imp…...

网络安全中的渗透测试主要那几个方面

渗透测试中主要有软件测试和渗透测试。 1、测试对象不同 软件测试&#xff1a;主要测试的是程序、数据、文档。 渗透测试&#xff1a;对象主要为网络设备、主机操作系统、数据库系统和应用系统。 2、测试内容不同 软件测试&#xff1a;主要工作内容是验证和确认&#xff0c;发…...

Cursor:GPT-4 驱动的强大代码编辑器

Cursor &#xff08;https://www.cursor.so/&#xff09;是 GPT-4 驱动的一款强大代码编辑器&#xff0c;可以辅助程序员进行日常的编码。下面通过一个实际的例子来展示 Cursor 如何帮助你编程。这个例子做的事情是网页抓取。抓取的目标是百度首页上的百度热搜&#xff0c;如下…...

C/C++中for语句循环用法及练习

目录 语法 下面是 for 循环的控制流&#xff1a; 实例 基于范围的for循环(C11) 随堂笔记&#xff01; C语言训练-计算1~N之间所有奇数之和 题目描述 输入格式 输出格式 样例输入 样例输出 环形方阵 干货直达 for 循环允许您编写一个执行特定次数的循环的重复控制结构。…...

AnimatorOverrideController说明

unity-AnimatorOverrideControllerhttps://docs.unity.cn/cn/current/ScriptReference/AnimatorOverrideController.html 用于控制动画器重写控制器的接口。 动画器重写控制器的用途是重写某个控制器的动画剪辑&#xff0c;从而为给定化身定制动画。 在运行时基于相同的 Anim…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...