当前位置: 首页 > 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…...

1.4、第三阶段 MySQL数据库

root数据库技术 一、数据库理论 1 什么是数据库技术 数据库技术主要研究如何组织、存储数据&#xff0c;并如何高效地提取和处理数据。 2 什么是SQL SQL&#xff08;Structured Query Language&#xff09;结构化查询语言 SQL是操作数据库的命令集&#xff0c;也是功能齐全的…...

LeetCode:202. 快乐数

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;202. 快乐数 题目描述&#xff1a;编写一个算法来判断一个数 n 是不是快…...

Android 14 新功能之 HighLights:快速实现文本高亮~

日常开发中可能会遇到给 TextView 的全部或部分文本增加高亮效果的需求&#xff0c;以前可能是通过 Spannable 或者 Html 标签实现。 升级 Android 14 后就不用这么迂回了&#xff0c;因其首次引入直接设置高亮的 API&#xff1a;HighLights。需要留意的是 HighLights API 和 …...

[渗透教程]-004-嗅探工具-Nmap

文章目录 Nmap介绍基本操作进阶操作Nmap介绍 nmap是一个网络扫描和主机检测工具,它可以帮助用户识别网络上的设备和服务。获取主机正在运行哪些服务,nmap支持多种扫描,UDP,TCP connect(),TCP SYN(半开扫描) ftp代理,反向标志,ICMP,FIN,ACK扫描,ftp代理,反向标志,ICMP. 可以用于…...

大数据技术之Hive SQL题库-初级

第一章环境准备1.1 建表语句hive>-- 创建学生表 DROP TABLE IF EXISTS student; create table if not exists student_info(stu_id string COMMENT 学生id,stu_name string COMMENT 学生姓名,birthday string COMMENT 出生日期,sex string COMMENT 性别 ) row format delim…...

常见HTTP状态码汇总

文章目录1xx: 信息2xx: 成功3xx: 重定向4xx: 客户端错误5xx: 服务器错误1xx: 信息 状态码描述100 Continue服务器仅接收到部分请求&#xff0c;但是一旦服务器并没有拒绝该请求&#xff0c;客户端应该继续发送其余的请求。101 Switching Protocols服务器转换协议&#xff1a;服…...

蓝桥杯刷题冲刺 | 倒计时15天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.年号字串2.裁纸刀3.猜生日1.年号字串 题目 链接&#xff1a; 年号字串 - 蓝桥云课 (lanqiao.c…...

【差分数组】

差分数组一维差分差分数组的作用差分矩阵结语一维差分 输入一个长度为 n 的整数序列。接下来输入 m个操作&#xff0c;每个操作包含三个整数 l,r,c&#xff0c;表示将序列中 [l,r] 之间的每个数加上 c &#xff0c;请你输出进行完所有操作后的序列。 输入格式 第一行包含两个…...

2022年NOC软件创意编程(学而思)决赛小学高年级组scratch

2022NOC决赛图形化小高组 一、选择题 1.运行下面的程序,最终“我的变量”的值是多少? 2.希望定义一个函数如下,可以让角色旋转指定的圈数。里面空缺的地方填上什么数字比较合适? 3.运行程序,在舞台上可以看见几个角色 ? 4.运行程序,角色会依次说什么 ? 5.我们都知…...

[JAVA]一步接一步的一起开发-图书管理系统(非常仔细,你一定能看懂)[1W字+]

目录 1.想法 2.框架的搭构 2.1图书 2.1.1Book类 2.1.2BookList类 2.2用户 2.2.1User抽象类 2.2.2AdminUser类&#xff08;管理者&#xff09; 2.2.3NormalUser 2.3操作 操作接口 借阅操作 删除操作 查询操作 归还图书 展示图书 退出系统 2.4小结 3.主函数的编…...