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

详解初阶数据结构之顺序表(SeqList)——单文件文件实现SeqList的增删查改

目录

一、线性表

二、顺序表

2.1概念及结构

2.2接口实现

2.3动态顺序表的创建

2.3动态顺序表的初始化

2.3.1传值初始化

2.3.2传址初始化

2.4动态顺序表的清空

2.5动态顺序表的扩容

2.6动态顺序表内容的打印

三、动态顺序表的使用

3.1尾插尾删

3.1.1尾插

3.1.2尾删

3.2头插头删

3.2.1头插

3.2.2头删

3.3在pos位置插入x

3.4删除pos位置的值

3.5修改某个位置的值

四、完整代码


一、线性表

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

二、顺序表

2.1概念及结构

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

顺序表一般分为:

静态顺序表:使用定长数组储存元素

//静态顺序表
#define N 100
struct SeqList
{int a[N];//定长数组int size;//有效数据的个数
};

 

缺点:不是很灵活

动态顺序表:使用动态开辟的数组储存。

2.2接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空
间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间
大小,所以下面我们实现动态顺序表。

所谓动态其实指的这个结构体里的指针是动态内存开辟来的,是可变的,用的时候动态开辟,不够的话继续开辟,程序结束的时候释放。

2.3动态顺序表的创建

typedef int SLDatatype;//将int重命名为SLDatatype
typedef struct SeqList
{SLDatatype* a;//指向动态开辟的数组SLDatatype capacity;//容量SLDatatype size;//有效数据的个数}SL;//将结构体SeqList重命名为SL

2.3动态顺序表的初始化

2.3.1传值初始化

//传值初始化
void SLInit(SL s)
{s.a = NULL;s.size = 0;s.capacity = 0;
}

 函数那个章节我们学过形参只是实参的临时拷贝,并没有实际作用,生命周期短,出了函数的作用域就会销毁,我们不考虑这种初始化方式。

2.3.2传址初始化

//传址初始化
void SLInit(SL* ps)
{ps->a = 0;ps->capacity = 0;ps->size = 0;
}
void SLInit(SL* ps)
{ps->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);//开辟了4个字节的空间if (ps->a == NULL){perror("malloc failed");exit(-1);}ps->capacity = 4;//开辟了空间就要给容量赋值ps->size = 0;
}

上面两种初始化方式都可以给予结构体成员变量赋值,但是我们使用第二种,因为第二种为我们开辟了空间。


2.4动态顺序表的清空

void SLDestr(SL* ps)
{free(ps->a);ps->a = NULL;ps->capacity = 0;//内存释放,容量清零ps->size = 0;//内存释放,有效数据清零
}

2.5动态顺序表的扩容

void SLCheckcapacity(SL* ps)
{if (ps->size == ps->capacity){SLDatatype* tmp = (SLDatatype*)realloc(ps->a, ps->capacity * 2 *( sizeof(SLDatatype)));//扩容尾原来的倍数if (tmp == NULL)//判断是否扩容失败{perror("realloc failed");exit(-1);}ps->a = tmp;ps->capacity *= 2;//扩容后修改原来的容量}
}

这就是所谓的动态,当我们空间不够时,就需要开辟新的空间,使用realloc函数要注意是否开辟成功,定义一个中间指针,当开辟成功时将这个指针赋值给动态数组中的指针。 

2.6动态顺序表内容的打印

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

size为有效数据个数,使用循环打印其中的有效数据。 

三、动态顺序表的使用

3.1尾插尾删

3.1.1尾插

void SLPushBack(SL* ps, SLDatatype x)
{SLCheckcapacity(ps);//检查空间是否足够插入ps->a[ps->size] = x;//赋值ps->size++;//插入一个有效数据,有效数据个数加一
}

 首先一定要检查规矩是否足够,根据上面开辟的空间,容量为4,有效数据为size为0,所以从第一个空间开始插入数据。

3.1.2尾删

//尾删
void SLPopBack(SL* ps)
{assert(ps->size > 0);//判断是否会造成越界if (ps->size == 0){return;}ps->size--;//删除一个数据,有效数据个数减一
}

插入数据后size的大小也会变化,数组中最后一个数字的下标刚好和size的大小一样我们只需要将size减1就行。 

3.2头插头删

3.2.1头插

void SLPushFront(SL* ps, SLDatatype x)
{SLCheckcapacity(ps);//检查空间是否足够int end = ps->size;while (end > 0){ps->a[end] = ps->a[end - 1];//将前一个数据后移动end--;}ps->a[0] = x;//将x赋给初始位置ps->size++;//加入一个数字,有效数据个数加1
}

 老规矩一定要检查空间是否足够,头部插入数据我们只需要将原来的数据往后移动一格就将第一格的位置空出来,再将数值插入就行,插入一个数据,有效数据加1即可。

3.2.2头删

void SLPopFront(SL* ps)
{assert(ps->size > 0);//防止越界访问if (ps->size==0){return;}int begin = 0;while (begin < ps->size){ps->a[begin] = ps->a[begin+1];//将后一个数据往前移动begin++;}ps->size--;//减少一个数字,有效数据减1
}

这里的删除并不是真正意义上的删除,我们只需要将原来的数据往前移动一位使后一位的数据覆盖在前一位,这就做到了删除,顺便再将有效数据减1就行。 

3.3在pos位置插入x

void SLInsert(SL* ps, int pos, int x)
{assert(pos >= 0 && pos <= ps->size);//防止越界访问SLCheckcapacity(ps);int end = ps->size;while (end >=pos){ps->a[end] = ps->a[end-1];//和头插的思想差不多,将数据后移end--;}ps->a[pos] = x;//将x赋值给pos位置ps->size++;//有效数据加1
}

我们可以这样理解:将pos看成初始位置,是不是就转化为头插了?按照头插的思想就可以完成在pos位置上插入x。 

3.4删除pos位置的值

void SLErase(SL* ps, int pos)
{assert(pos >= 0 && pos <= ps->size);//防止越界访问SLCheckcapacity(ps);int begin = pos;while (begin < ps->size){ps->a[begin] = ps->a[begin + 1];//和头删的思想差不多,将数据前移begin++;}ps->size--;//有效数据减1
}

我们会发现3.4和3.5不仅可以做到某个位置值的插入和删除,也可以做到尾插尾删和头插头删。 

3.5修改某个位置的值

void SLModify(SL* ps, SLDatatype pos, SLDatatype x)
{assert(pos >= 0 && pos < ps->size);//防止越界ps->a[pos] = x;
}

 这样修改某个位置的值看起来是挺麻烦,但是是为了安全考虑。

四、完整代码

#define _CRT_SECURE_NO_WARNINGS 67
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//静态顺序表
//#define N 100
//struct SeqList
//{
//	int a[N];//定长数组
//	int size;//有效数据的个数
//};//动态顺序表//创建
typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;//指向动态开辟的数组SLDatatype capacity;//容量SLDatatype size;//有效数据的个数}SL;
//传值初始化
//void SLInit(SL s)
//{
//	s.a = NULL;
//	s.size = 0;
//	s.capacity = 0;
//}
//传址初始化
//void SLInit(SL* ps)
//{
//	ps->a = 0;
//	ps->capacity = 0;
//	ps->size = 0;
//}
void SLInit(SL* ps)
{ps->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);//开辟了4个字节的空间if (ps->a == NULL){perror("malloc failed");exit(-1);}ps->capacity = 4;ps->size = 0;
}
//清空
void SLDestr(SL* ps)
{free(ps->a);ps->a = NULL;ps->capacity = 0;ps->size = 0;
}
//打印
void SLprint(SL* ps)
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
//检查容量
void SLCheckcapacity(SL* ps)
{if (ps->size == ps->capacity){SLDatatype* tmp = (SLDatatype*)realloc(ps->a, ps->capacity * 2 *( sizeof(SLDatatype)));//扩容尾原来的倍数if (tmp == NULL){perror("realloc failed");exit(-1);}ps->a = tmp;ps->capacity *= 2;}
}
//尾插
void SLPushBack(SL* ps, SLDatatype x)
{SLCheckcapacity(ps);ps->a[ps->size] = x;ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{assert(ps->size > 0);if (ps->size == 0){return;}ps->size--;
}
//头插
void SLPushFront(SL* ps, SLDatatype x)
{SLCheckcapacity(ps);int end = ps->size;while (end > 0){ps->a[end] = ps->a[end - 1];end--;}ps->a[0] = x;ps->size++;
}
//头删
void SLPopFront(SL* ps)
{assert(ps->size > 0);if (ps->size==0){return;}int begin = 0;while (begin < ps->size){ps->a[begin] = ps->a[begin+1];begin++;}ps->size--;
}
//在pos位置插入x
void SLInsert(SL* ps, int pos, int x)
{assert(pos >= 0 && pos <= ps->size);SLCheckcapacity(ps);int end = ps->size;while (end >=pos){ps->a[end] = ps->a[end-1];end--;}ps->a[pos] = x;ps->size++;
}
//删除pos位置的值
void SLErase(SL* ps, int pos)
{assert(pos >= 0 && pos <= ps->size);SLCheckcapacity(ps);int begin = pos;while (begin < ps->size){ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;
}
int SLFind(SL* ps, int x)
{int i = 0;for (i = 0; i < ps->size; i++){if (ps->a[i] == x)return i;}return -1;
}void SLModify(SL* ps, SLDatatype pos, SLDatatype x)
{assert(pos >= 0 && pos < ps->size);ps->a[pos] = x;
}
int main()
{SL s1;//传值初始化//SLInit(s1);//传址初始化SLInit(&s1);//尾插SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPushBack(&s1, 7);//尾插测试printf("尾插:\n");SLprint(&s1);//尾删SLPopBack(&s1);//尾删测试printf("尾删:\n");SLprint(&s1);//头插SLPushFront(&s1,10);//头插测试printf("头插:\n");SLprint(&s1);//头删 SLPopFront(&s1);//头删测试printf("头删:\n");SLprint(&s1);//在pos位置插入xSLInsert(&s1, 0, 100);//pos插入x测试printf("pos位置插入x\n");SLprint(&s1);//删除pos位置的值SLErase(&s1, 0);//测试printf("删除pos位置的值\n");SLprint(&s1);//改SLModify(&s1, 2, 1);printf("修改某个位置上的值:\n");//SLprint(&s1);//清空SLDestr(&s1);return 0;
}

 

相关文章:

详解初阶数据结构之顺序表(SeqList)——单文件文件实现SeqList的增删查改

目录 一、线性表 二、顺序表 2.1概念及结构 2.2接口实现 2.3动态顺序表的创建 2.3动态顺序表的初始化 2.3.1传值初始化 2.3.2传址初始化 2.4动态顺序表的清空 2.5动态顺序表的扩容 2.6动态顺序表内容的打印 三、动态顺序表的使用 3.1尾插尾删 3.1.1尾插 3.1.2尾删…...

JavaScript中的深拷贝和浅拷贝

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;⭐深拷贝&#xff08;Deep Copy&#xff09;&#xff1a;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带…...

树形结构的节点作为查询参数业务

1、业务描述 有一个树结构&#xff0c;存在一个唯一的code和一个父节点的pcode&#xff0c;要求前端传入任意层的code匹配这个code对应的所有子节点对应的数据。 2、解决思路 因为无法判定传入的code到底在那层&#xff0c;so 直接递归调用查询判断&#xff0c;如果有子节点就…...

sql:SQL优化知识点记录(十二)

&#xff08;1&#xff09;读锁案例讲解 加读锁和写锁 查看是否上锁&#xff1a;In_use&#xff1a;变成了1 读写锁对我们数据产生哪些影响&#xff1a; 读锁&#xff1a;是共享锁&#xff0c;其他线程可以查看&#xff1a; 加了读锁&#xff1a;session1不能修改自己&#xf…...

一.使用qt creator 设计显示GUI

一.安装qt creator 二.创建项目 文件-》新建项目 三.使用设计 可以直接使用鼠标拖拽 四.转换为py文件 # from123.py 为导出 py文件的文件名 form.ui 为 qt creator创造的 ui 文件 pyuic5 -o x:\xxx\from123.py form.ui五.显示GUI from PyQt5.QtWidgets import * fr…...

sql:SQL优化知识点记录(八)

&#xff08;1&#xff09;索引面试题分析 所谓索引&#xff1a;就是排好序的快速查找数据结构&#xff0c;排序家查找是索引的两个用途 select * 在where使用到了索引&#xff0c;当select * 有模糊查询%在左边索引会失效 当select * where后面索引的顺序发生变化&#xff0…...

java笔试题,寻找多出来的元素

题目&#xff1a;有两个数组a和b&#xff0c;其中b有一个元素是a没有的&#xff0c;其他元素都相同&#xff0c;请找出b中这个多余的元素。 1 public class Test02 { 2 3 public static void main(String[] args) { 4 int[] a {11, 34, 9, -4, 100, 98}; 5 int[] b {34…...

docker笔记3 Docker常规安装

1.安装tomcat docker hub上面查找tomcat镜像 docker search tomcat 从docker hub上拉取tomcat镜像到本地 docker pull tomcat docker images查看是否有拉取到的tomcat 使用tomcat镜像创建容器实例(也叫运行镜像) docker run -it -p 8080:8080 tomcat -p 小写&#xff0c;主…...

阻止 NTLM后无法登录远程桌面的原因

阻止 NTLM(NT LAN Manager) 攻击设置二 之前郑州景安的服务器被攻击&#xff0c;没过几天阿里云的也被攻击&#xff0c;且都是 NTLM 攻击。 Operating System: Windows Server 2008(R2) Enterprise Service Pack 1 64bit 一、winr 输入 gpedit.msc 二、依次进入&#xff1a;…...

Docker网络功能

基本网络功能 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。使用docker network子命令来管理Docker网络。 外部访问容器可通过端口映射实现&#xff0c;启动容器时使用-p参数指定映射关系。-p可多次使用来绑定多个端口。使用docker port命令查看当前映射的端…...

如何入门 AI----如何确定学习目标

当确定学习人工智能&#xff08;AI&#xff09;的目标时&#xff0c;可以考虑以下具体的步骤&#xff1a; 兴趣和好奇心&#xff1a; 首先&#xff0c;问问自己&#xff0c;您对哪些 AI 领域感兴趣&#xff1f;是机器学习、自然语言处理、计算机视觉&#xff0c;还是其他领域&a…...

ABAP中加前导零和去前导零方法

文章目录 1 Introduction2 Method 1 Introduction In the sap there are two method for leading zero. We can use function or use the below the method . 2 Method SELECT * INTO TABLE DATA(IT_ITEM)FROM MARA .LOOP AT IT_ITEM ASSIGNING FIELD-SYMBOL(<FS_DATA&g…...

聊聊ShardingSphere是怎么进行sql重写的

序 本文主要研究一下ShardingSphere进行sql重写的原理 prepareStatement org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java public final class ShardingSphereConnection extends AbstractConnectionAdapter {Overridepublic Prepar…...

软件设计模式系列之二——抽象工厂模式

1 抽象工厂模式的定义 抽象工厂模式是一种创建型设计模式&#xff0c;它提供了一种创建一组相关或相互依赖对象的方式&#xff0c;而无需指定它们的具体类。该模式以一组抽象接口为核心&#xff0c;包括抽象工厂接口和一组抽象产品接口&#xff0c;每个具体工厂类负责创建特定…...

P2719 搞笑世界杯 (期望dp

#include <bits/stdc.h> using namespace std; using VI vector<int>;double dp[2000][2000]; int n; //求dp[2][0] //dp[0][2] //期望dp要从终末态&#xff0c;向起始态转移 //dp[a][b] - > dp[a][b-1] or dp[a-1][b] //dp[a][b] 1/2 * dp[a][b1] 1/2 * dp…...

spring cloud新版本使用loadbalancer替代Ribbon

Nacos 2021 不再集成 Ribbon&#xff0c;建议使用spring cloud loadbalancer 引入 一、简单使用 引入依赖spring cloud loadbalancer <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer<…...

【Git-Exception】Git报错:fatal: unable to auto-detect email address

报错信息&#xff1a; *** Please tell me who you are. Run git config --global user.email “youexample.com” git config –global user.name “Your Name” to set your account’s default identity. Omit --global to set the identity only in this repository. fatal…...

JVM性能优化 —— 类加载器,手动实现类的热加载

一、类加载的机制的层次结构 每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑&#xff0c;这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件&#xff0c;”.class”文件中保存着Java代码经转换后的虚拟机指令&#xff0c;当需要使用某个类时&#…...

SSH连接MobaXterm

IT常用软件的安装 ssh连接MobaXterm详细使用教程 数据库Navicat安装&#xff1a;https://www.jianshu.com/p/2494e02caf63 java SE安装 https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html windows安装pip https://www.cnblogs.com/NanShan2016/…...

本地虚机Jumpserver使用域名访问报错 使用IP+端口没有错误

背景&#xff1a; 我在本地Windows VMware 15的环境中部署了CentOS7.5&#xff0c;下载jumpserver-offline-installer-v2.28.1-amd64-138.tar.gz并安装部署。 需求&#xff1a; 1、能使用http:ip访问堡垒机。达成&#xff1b; 2、能使用http:域名访问堡垒机。达成&#xff…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...