手撕顺序表
> 作者简介:დ旧言~,目前大一,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。
> 望小伙伴们点赞👍收藏✨加关注哟💕💕

🌟前言
梦回数组,当我们开辟了一个数组,数组的大小就已经确定了,不能括容,也不能减容,为了解决这个问题,在数据结构有一个这样的知识--《顺序表》。顺序表连续开辟一个空间,能括容,也能减容,今天我们手撕顺序表。

🌙主体
咱们从三个方面实现顺序表,动态管理,头插头删尾插尾删,增删查改。

在程序中为了实现顺序表,需要创建头文件SeqList.h ,创建源文件test.c,SeqList.c。

🌠动态管理
💤初始化动态顺序表
- 首先定义一个结构体(在源文件中),结构体里面有可变数组(a),数组初始长度(size),初始空间(capacity)。
- 初始化动态顺序表(SeqList.h中),需要开辟空间,再判断空间是否为空,再初始化数组长度,空间。
//动态顺序表
typedef int SLDataType;
typedef struct SeqList
{//定义一个可变数组SLDataType* a;//定义数组初始长度int size;//定义空间大小int capacity;
}SL;//初始化动态顺序表
void SLInit(SL* ps)
{//开辟空间ps->a = (SLDataType*)malloc(sizeof(SLDataType*) * 4);//判断空间是否为空if (ps->a == NULL){perror("malloc failed");exit(-1);}//初始化ps->size = 0;ps->capacity = 4;
}
1.防止一直创建结构体,为了一劳永逸,我们把动态顺序表放在源文件中。
2.这里我们用typedef int SLDataType,给数据类型重定义名字,这样就可以防止修改数据类型。
💤扩容顺序表空间
当数组初始长度(size),初始空间(capacity)相同时,这里们就需要扩容,这里我们扩容两倍。(在头文件中SeqList.h中)
//扩容空间
void SLCheckCapacity(SL* ps)
{//如果size和capacity相同if (ps->size == ps->capacity){//扩大两倍SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(SLDataType));//判断tmp是否为空if (tmp == NULL){perror("realloc failed");exit(-1);}//赋值ps->a = tmp;ps->capacity = ps->capacity * 2;}
}
💤释放顺序表内存
可变数组(a)置为(NULL),数组长度(size)置为(0),初始空间(capacity)置为(0)。
//释放内存
void SLDestroy(SL* ps)
{//断言assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
🌠头插头删尾插尾删
💤添加元素
首先需要断言防止顺序表为空。这里需要注意空间是否满了。这里的实现和在pos位置插入x有类似,等我们实现这个函数,就可以直接调用这个函数,更加简便。(在头文件中SeqList.h中)
//添加元素
void SLPushBack(SL* ps, SLDataType x)
{//断言assert(ps);//判断空间是否满了,需要调用函数SLCheckCapacity(ps);//添加元素ps->a[ps->size] = x;ps->size++;//在pos位置插入x//SLInsert(ps, ps->size, x);
}
💤打印元素
打印元素太简单啦,直接用for循环就行。(在头文件中SeqList.h中)
//打印数组
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
💤尾删
直接在末尾删除就行,之后这里只要size减减就好了,后面的元素会覆盖。这里的实现和在pos位置插入x有类似,等我们实现这个函数,就可以直接调用这个函数,更加简便。(在头文件中SeqList.h中)
//尾删
void SLPopBack(SL* ps)
{//断言assert(ps);// 温柔的检查//if (ps->size == 0)//return;// 暴力的检查assert(ps->size > 0);//ps->a[ps->size - 1] = 0;//这里只要size减减就好了,后面的元素会覆盖ps->size--;//删除pos位置的值//SLErase(ps, ps->size - 1);
}
💤头插(重点)

这里需要注意要让ps->size加加,这里的实现和在pos位置插入x有类似,等我们实现这个函数,就可以直接调用这个函数,更加简便。(在头文件中SeqList.h中)
//头插
void SLPushFront(SL* ps, SLDataType x)
{//断言assert(ps);//定义最后一个元素int end = ps->size - 1;//循环while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}//x赋给最前的数字ps->a[0] = x;//指向下一个数字ps->size++;//在pos位置插入x//SLInsert(ps, 0, x);
}
💤头删(重点)

这里需要注意要让ps->size减减,这里的实现和删除pos位置的值相似,等我们实现这个函数,就可以直接调用这个函数,更加简便。(在头文件中SeqList.h中)
//头删
void SLPopFront(SL* ps)
{//断言assert(ps);//断言(指向不能为零)assert(ps);//指向头前面的那个数字int begin = 1;//循环while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;//删除pos位置的值//SLErase(ps, 0);
}
🌠增删查改
💤在pos位置插入x
首先这里需要判断pos是否在数组空间内,其次判断空间是否充足,然后循环,最后ps->size++
这里的插入本质和头插相似。(元素向后移动一格)

//在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x)
{//断言,这里posassert(ps);assert(pos >= 0 && pos < ps->size);//内存不够需要括容SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
💤删除pos位置的值
首先这里需要判断pos是否在数组空间内,其次判断空间是否充足,然后循环,最后ps->size--
这里的删除本质和头删相似。(元素向前移动一格)

//删除pos位置的值
void SLErase(SL* ps, int pos)
{//断言assert(ps);//断言posassert(pos >= 0 && pos < ps->size);int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];++begin;}ps->size--;
}
💤修改pos位置的信息
这个实现太简单啦。
//修改pos位置的信息
void SLModify(SL* ps, int pos, SLDataType x)
{//断言assert(ps);//判断posassert(pos >= 0 && pos < ps->size);//直接换ps->a[pos] = x;
}
🌠主函数
int main()
{//定义结构体SL sl;//初始动态列表SLInit(&sl);//释放内存SLDestroy(&sl);return 0;
}
🌙代码总结
🌠主函数
//主函数(包含头文件)
#include"SeqList.h"//尾删
void TestSeqList1()
{//定义结构体SL sl;//初始化SLInit(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);SLPushBack(&sl, 6);SLPushBack(&sl, 6);SLPushBack(&sl, 0);SLPushBack(&sl, 0);//打印元素SLPrint(&sl);//尾删SLPopBack(&sl);SLPopBack(&sl);//打印元素SLPrint(&sl);//尾删SLPopBack(&sl);SLPopBack(&sl);SLPopBack(&sl);SLPopBack(&sl);SLPopBack(&sl);SLPopBack(&sl);SLPopBack(&sl);//打印元素SLPrint(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);//打印元素SLPrint(&sl);//释放内存SLDestroy(&sl);
}//头删
void TestSeqList2()
{//定义结构体SL sl;//初始动态列表SLInit(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);//打印元素SLPrint(&sl);//头插SLPushFront(&sl, 10);SLPushFront(&sl, 20);SLPushFront(&sl, 30);SLPushFront(&sl, 40);//头删SLPopFront(&sl);SLPopFront(&sl);SLPopFront(&sl);//打印元素SLPrint(&sl);//释放内存SLDestroy(&sl);
}//在pos位置插入x
void TestSeqList3()
{//定义结构体SL sl;//初始动态列表SLInit(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);//打印元素SLPrint(&sl);//在pos位置插入xint input = 0;printf("请输入插入的位置:");scanf("%d", &input);int number = 0;printf("请输入插入的数字:");scanf("%d", &number);SLInsert(&sl, input, number);//打印元素SLPrint(&sl);//释放内存SLDestroy(&sl);
}//删除pos位置的值
void TestSeqList4()
{//定义结构体SL sl;//初始动态列表SLInit(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);//打印元素SLPrint(&sl);//删除pos位置的值int input = 0;printf("请输入删除的位置:");scanf("%d", &input);SLErase(&sl, input);//打印元素SLPrint(&sl);//释放内存SLDestroy(&sl);
}//删除pos位置的值
void TestSeqList5()
{//定义结构体SL sl;//初始动态列表SLInit(&sl);//添加元素SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(&sl, 5);//打印元素SLPrint(&sl);//修改pos位置的信息int input = 0;printf("请输入需要修改的位置:");scanf("%d", &input);int number = 0;printf("请输入需要修改的数字:");scanf("%d", &number);SLModify(&sl, input, number);//打印元素SLPrint(&sl);//释放内存SLDestroy(&sl);
}int main()
{//TestSeqList1();//TestSeqList2();//TestSeqList3();//TestSeqList4();TestSeqList5();return 0;
}
🌠SeqList.h源文件
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//动态顺序表
typedef int SLDataType;
typedef struct SeqList
{//定义一个可变数组SLDataType* a;//定义数组初始长度int size;//定义空间大小int capacity;
}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);//头删//返回下标,没有找打返回-1
int SLFind(SL* ps, SLDataType x);
//在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x);
//删除pos位置的值
void SLErase(SL* ps, int pos);
//修改pos位置的信息
void SLModify(SL* ps, int pos, SLDataType x);
🌠SeqList.c头文件
#include"SeqList.h"//初始化动态顺序表
void SLInit(SL* ps)
{//开辟空间ps->a = (SLDataType*)malloc(sizeof(SLDataType*) * 4);//判断空间是否为空if (ps->a == NULL){perror("malloc failed");exit(-1);}//初始化ps->size = 0;ps->capacity = 4;
}//释放内存
void SLDestroy(SL* ps)
{//断言assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}//打印数组
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//扩容空间
void SLCheckCapacity(SL* ps)
{//如果size和capacity相同if (ps->size == ps->capacity){//扩大两倍SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(SLDataType));//判断tmp是否为空if (tmp == NULL){perror("realloc failed");exit(-1);}//赋值ps->a = tmp;ps->capacity = ps->capacity * 2;}
}//添加元素
void SLPushBack(SL* ps, SLDataType x)
{//断言assert(ps);/*//判断空间是否满了,需要调用函数SLCheckCapacity(ps);//添加元素ps->a[ps->size] = x;ps->size++;*///在pos位置插入xSLInsert(ps, ps->size, x);
}//尾删
void SLPopBack(SL* ps)
{//断言assert(ps);/*// 温柔的检查//if (ps->size == 0)//return;// 暴力的检查assert(ps->size > 0);//ps->a[ps->size - 1] = 0;//这里只要size减减就好了,后面的会覆盖ps->size--;*///删除pos位置的值SLErase(ps, ps->size - 1);
}//头插
void SLPushFront(SL* ps, SLDataType x)
{//断言assert(ps);/*//定义最后一个元素int end = ps->size - 1;//循环while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}//x赋给最前的数字ps->a[0] = x;//指向下一个数字ps->size++;*///在pos位置插入xSLInsert(ps, 0, x);
}//头删
void SLPopFront(SL* ps)
{//断言assert(ps);/*//断言(指向不能为零)assert(ps);//指向头前面的那个数字int begin = 1;//循环while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;*///删除pos位置的值SLErase(ps, 0);
}//返回下标,没有找打返回-1
int SLFind(SL* ps, SLDataType x)
{//断言assert(ps);//遍历for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i;}}return -1;
}//在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x)
{//断言,这里posassert(ps);assert(pos >= 0 && pos < ps->size);//内存不够需要括容SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}//删除pos位置的值
void SLErase(SL* ps, int pos)
{//断言assert(ps);//断言posassert(pos >= 0 && pos < ps->size);int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];++begin;}ps->size--;
}//修改pos位置的信息
void SLModify(SL* ps, int pos, SLDataType x)
{//断言assert(ps);//判断posassert(pos >= 0 && pos < ps->size);//直接换ps->a[pos] = x;
}
🌟结束语
今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小说手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

相关文章:
手撕顺序表
> 作者简介:დ旧言~,目前大一,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 望小伙伴们点赞👍收藏✨加关注哟💕…...
Python实战项目——旅游数据分析(四)
由于有之前的项目,所以今天我们直接开始,不做需求分析,还不会需求分析的可以看我之前的文章。Python实战项目——用户消费行为数据分析(三) 导入库 import numpy as np import pandas as pd import matplotlib.pyplo…...
前端CryptoJS-AES加解密 对应php的AES-128-CBC加解密踩坑(java也相同加解密)
前端部分注意看填充是pkcs7 有个前提,要看前端有没有转成hex格式,如果没转,php那边就不需要调用特定函数转hex格式的 const keyStr 5hOwdHxpW0GOciqZ;const iv 0102030405060708;//加密function Encrypt(word) {let key CryptoJS.enc.Ut…...
Python解码张三的法外狂徒之旅,揭秘视频背后的真相!【含jS逆向解密】
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 传说中,有人因为只是远远的看了一眼法外狂徒张三就进去了😂 我现在是获取他视频,岂不是直接终生了🤩 网友:赶紧跑路吧 😏 好了话不多说ÿ…...
【解析】对比学习和孪生网络的关系
文章目录 区别联系具体概念孪生网络(Siamese Networks)对比学习(Contrastive Learning) 区别 孪生网络是一种特定的神经网络结构;对比学习是一种学习策略,它试图让模型学习如何区分正样本对(相…...
Java版本企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...
智能井盖:科技赋能城市脚下安全
在智能化飞速发展的今天,智能井盖作为城市基础设施的一部分,正逐渐走进人们的视野。它利用现代科技手段,实现了对城市井盖的实时监控、及时响应和高效管理,为城市管理、市民出行等方面带来了诸多便利。 城市中井盖数量庞大&#x…...
wangeditor编辑器配置
vue项目中使用编辑器,轻量,操作栏选取自己需要的 官网地址:用于 Vue React | wangEditor 使用在vue项目中引入 npm install wangeditor/editor --savenpm install wangeditor/editor-for-vue --save 封装成组件使用 <template>&…...
Sqlite使用WAL模式指南
本文地址:http://t.csdn.cn/kE8ND 文章目录 一、WAL模式的原理二、开启WAL后必须要设置的参数1.PRAGMA SYNCHRONOUS(1)SYNCHRONOUS的类型(2)WAL下如何选择SYNCHRONOUS类型 2.PRAGMA wal_autocheckpoint3.sqlite3_busy…...
一套高质量可靠的 React Hooks 库
个人使用,感受,挺好用 https://ahooks.js.org/zh-CN 我主要用了这个 useCountDown 倒计时,再也不用费心费力去写一个倒计时方法了,而且直接提供end之后要做什么。...
集合---list接口及实现类
一、list概述 1、list接口概述 List接口继承自Collection接口,是单列集合的一一个重要分支,我们习惯性地会将实现了 List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方 式进行有序存储的,在…...
JVM简述
JDK&JRE&JVMJVM运行时内存结构图方法区堆区栈区程序计数器本地方法栈 JVM 的主要组成部分及其作用 JDK&JRE&JVM JVM就是java虚拟机,一台虚拟的机器,用来运行java代码 但并不是只有这台机器就可以的,java程序在运行时需要依赖…...
7.25训练总结
考场错误: A题其实并不简单,但是先想了一个方法后,就交了,wa了后一直卡住,策略不当,到最后后期写C的时候也犯了一些低级的错误,这点需要注意。 之后顺利的把BCDHI写完后,又完成了A的…...
java注解@FeignClient修饰的类路径不在spring boot入口类所在的包下,有哪几种处理方式?
一、注解EnableFeignClients 修饰在spring boot入口类,使得openfeign的FeignClient注解生效。 我们进一步看看注解EnableFeignClients的使用方式。 String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] clie…...
神经网络随记-参数矩阵、剪枝、模型压缩、大小匹配、、
神经网络的参数矩阵 在神经网络中,参数矩阵是模型学习的关键部分,它包含了神经网络的权重和偏置项。下面是神经网络中常见的参数矩阵: 权重矩阵(Weight Matrix):权重矩阵用于线性变换操作,将输…...
4、Kubernetes 集群 YAML 文件详解
目录 一、YAML 概述 二、YAML 基本语法 三、YAML 数据结构 四、k8s资源清单描述方法 五、YAML 快速编写 1、使用 kubectl create 命令 2、使用 kubectl get 命令导出 yaml 文件 一、YAML 概述 k8s 集群中对资源管理和资源对象编排部署都可以通过声明YAML文件来解决&…...
leetcode93. 复原 IP 地址(java)
复原 IP 地址 leetcode93. 复原 IP 地址回溯算法代码演示 回溯算法 leetcode93. 复原 IP 地址 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。 例如:“0.1.2…...
极光Java 版本服务器端实现别名消息推送
文章目录 引言I 概述1.1 依赖包1.2 极光证书环境参数1.3 构建推送对象II 推送内容2.1 配置推送内容2.2 获取通知消息内容2.3 配置IOS通知内容2.4 配置Android通知内容2.5 发起推送2.6 分批推送2.7 初始化密钥2.8 配置密钥引言 REST API 文档:https://docs.jiguang.cn/jpush/se…...
【Lua学习笔记】Lua进阶——Table(4)继承,封装,多态
文章目录 封装继承多态 封装 // 定义基类 Object {}//由于表的特性,该句就相当于定义基类变量 Object.id 1//该句相当于定义方法,Object可以视为定义的对象,Test可以视为方法名 //我们知道Object是一个表,但是抽象地看ÿ…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
