(数据结构)顺序表实现-增删查改

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.顺序表

2.1概念及结构

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

顺序表就是数组,但是在数组的基础上,它还要数据是连续存储的,不能跳跃间隔。

#pragma once
#define N 100
typedef int SLDataType;//静态顺序表
typedef struct SeqList
{SLDataType arr[N];int size;//表示数组中存了多少个数据
}SL;//接口函数
//静态特点:满了就不让插入,很难确定给多少空间void SeqListInit(SL* ps);
//尾插
void SeqListPushBack(SL* ps, SLDataType x);
//尾删
void SeqListPopBack(SL* ps);
//头插
void SeqListPushFront(SL* ps, SLDataType x);
//头删
void SeqListPopFront(SL* ps);

静态顺序表不够灵活,我们接下来要学习的是动态顺序表;

学习动态顺序表前先说一个我犯过的错误,希望你们可以避一下

所以要传的是地址

顺序表一般可以分为:

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

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

3.顺序表的实现

3.1尾插:在顺序表末尾插入数据

实现步骤:

1.检查空间是否足够,不足需要继续开辟空间

1.1如果容量为0先分配一个初始容量,后面容量不够可以进行2倍扩容

1.2通过realloc开辟空间,将这个空间的地址赋值给一个定义的指针变量

1.3如果这个指针变量为NULL,即空间开辟失败进行相应的保护

1.4令顺序表的空间地址等于定义的指针变量,同时将新的容量赋值给原容量

2.空间足够

2.1将数据直接插入当前顺序表尾部

2.2++当前的有效数据个数

void SeqListPushBack(SL* ps, SLDataType x)
{//当空间为0或空间不够时,要开辟空间if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp=(SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror(realloc);exit(-1);//不可以写return -1;因为return没有终止掉程序}ps->a = tmp;ps->capacity = newcapacity;}//空间充足,直接插入数据即可ps->a[ps->size] = x;ps->size++;
}

如果对动态内存管理的函数不太了解可以看看我这一篇文章:

理清C语言中动态内存管理相关函数-CSDN博客

3.2尾删

直接减小size就行

void SeqListPopBack(SL* ps)
{//两种方式都可以/*if (ps->size > 0){ps->size--;}*/assert(ps->size > 0);ps->size--;
}

3.3头插

和尾插一样,先判断空间是否充足

为了方便我直接将扩容的功能封装成一个函数

void SeqListCheckcapacity(SL* ps)
{//当空间为0或空间不够时,要开辟空间if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror(realloc);exit(-1);//不可以写return -1;因为return没有终止掉程序}ps->a = tmp;ps->capacity = newcapacity;}
}

头插数据最简单的方法就是把现在数组的数据都往后挪一位,再把要插入的数据放在顺序表头部

void SeqListPushFront(SL* ps, SLDataType x)
{SeqListCheckcapacity(ps);//挪动数据int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}

3.4头删

从第二个数据开始往前挪,覆盖第一个数据,然后size-1

void SeqListPopFront(SL* ps)
{assert(ps->size > 0);int start = 0;while (start < ps->size-1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

3.5搜寻数据

遍历一遍顺序表即可

//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDataType x)
{int j = -1;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){j = i;}}return j;
}

3.6在指定位置插入数据

和头插的逻辑一样,也是将数据往后挪

void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(pos >= 0 || pos <= ps->size);SeqListCheckcapacity(ps);//空间充足int end = ps->size-1;while (end >=pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;}

3.7删除指定位置的数据

//删除pos位置的数据
void SeqListErase(SL* ps, int pos)
{SeqListCheckcapacity(ps);int start = pos;while (start < ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

3.9销毁顺序表

void SeqListDestory(SL* ps)
{free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0;
}

完整的工程:

main.c

#define _CRT_SECURE_NO_WARNINGS
#include "SeqList.h"void TestList1();int main()
{TestList1();return 0;
}void TestList1()
{SL plist;SeqListInit(&plist);SeqListPushBack(&plist, 1);SeqListPushBack(&plist, 2);SeqListPushBack(&plist, 3);SeqListPushBack(&plist, 4);SeqListPushBack(&plist, 5);//        ListPushFront(plist, 0);SeqListPrint(&plist);}

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 SeqListInit(SL* ps);
//尾插
void SeqListPushBack(SL* ps, SLDataType x);
//尾删
void SeqListPopBack(SL* ps);
//头插
void SeqListPushFront(SL* ps, SLDataType x);
//头删
void SeqListPopFront(SL* ps);
//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDataType x);
//指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x);
//删除pos位置的数据
void SeqListErase(SL* ps, int pos);//打印顺序表
void SeqListPrint(SL* ps);
//销毁顺序表
void SeqListDestory(SL* ps);
//查看顺序表空余的容量
void SeqListCheckcapacity(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS
#include "SeqList.h"//初始化
void SeqListInit(SL* ps)
{ps->a = NULL;ps->size = ps->capacity = 0;
}void SeqListDestory(SL* ps)
{free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0;
}void SeqListPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SeqListCheckcapacity(SL* ps)
{//当空间为0或空间不够时,要开辟空间if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){//perror(realloc);exit(-1);//不可以写return -1;因为return没有终止掉程序}ps->a = tmp;ps->capacity = newcapacity;}
}//尾插:在顺序表末尾插入数据
void SeqListPushBack(SL* ps, SLDataType x)
{//当空间为0或空间不够时,要开辟空间if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){//perror(realloc);exit(-1);//不可以写return -1;因为return没有终止掉程序}ps->a = tmp;ps->capacity = newcapacity;}//空间充足,直接插入数据即可ps->a[ps->size] = x;ps->size++;
}//尾删
void SeqListPopBack(SL* ps)
{//两种方式都可以/*if (ps->size > 0){ps->size--;}*/assert(ps->size > 0);ps->size--;
}//头插
void SeqListPushFront(SL* ps, SLDataType x)
{SeqListCheckcapacity(ps);//挪动数据int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}
//头删
void SeqListPopFront(SL* ps)
{assert(ps->size > 0);int start = 0;while (start < ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDataType x)
{int j = -1;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){j = i;}}return j;
}//指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(pos >= 0 || pos <= ps->size);SeqListCheckcapacity(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 SeqListErase(SL* ps, int pos)
{SeqListCheckcapacity(ps);int start = pos;while (start < ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

上一篇:

算法的时间复杂度和空间复杂度_算法复杂度 计算复杂度和存储复杂度-CSDN博客

下一篇:

(数据结构)链表-CSDN博客

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

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

相关文章

【面试八股总结】线程/进程同步问题

一、同步与互斥 在线程并发执行的过程中&#xff0c;进程/线程之间存在协作的关系&#xff0c;例如有互斥、同步的关系。为了实现进程/线程间正确的协作&#xff0c;操作系统必须提供实现进程协作的措施和方法&#xff0c;主要的方法有两种&#xff1a; 锁&#xff1a;加锁、解…

大语言模型提示工程与应用:提示工程入门指南

提示工程入门 学习目标 在本课程中&#xff0c;我们将学习提示工程。 相关知识点 提示工程 学习内容 1 提示工程 提示工程是一门新兴学科&#xff0c;专注于设计和优化提示词以高效利用语言模型完成多样化任务。掌握提示工程能帮助开发者更深入理解大语言模型(LLM)的能力…

PostgreSQL 多级依赖血缘系统的设计与落地

一、业务背景&#xff1a;三类指标与四种状态指标类型定义规则依赖关系原子指标单表聚合&#xff08;SELECT WHERE GROUP&#xff09;无派生指标在原子/派生指标上加 WHERE、改 GROUP依赖 1~N 个父指标复合指标多个原子/派生指标做加减运算依赖 1~N 个父指标状态说明已保存草…

阿里云百炼平台创建智能体-上传文档

整体思路是&#xff1a; 1创建ram用户&#xff0c;授权 2上传文件获取FileSession 3调用智能体对话&#xff0c;传入FileSession 接下来每个步骤的细节&#xff1a; 1官方不推荐使用超级管理员用户获得accessKeyId和accessKeySecret&#xff0c;所以登录超级管理员账号创建…

剪映里面导入多张照片,p图后如何再导出多张照片?

剪映普通版本暂时没发现可以批量导出图片。这里采用其他方式实现。先整体导出视频。这里前期要注意设置帧率&#xff0c;一张图片的时长。 参考一下设置&#xff0c;帧率设置为30&#xff0c;图片导入时长设置为1s&#xff0c;这样的话&#xff0c;方便后期把视频切割为单帧。导…

怎么查看Linux I2C总线挂载了那些设备?

1. 根据系统启动查看设备树节点文件&#xff08;系统运行后的&#xff09; 比如&#xff1a;要查看I2C2i2c2: i2cfeaa0000 {compatible "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";reg <0x0 0xfeaa0000 0x0 0x1000>;clocks <&cru CLK_…

bat脚本实现获取非微软官方服务列表

Get-CimInstance -ClassName Win32_Service |Where-Object { $_.State -eq Running -and $_.StartMode -ne Disabled } | ForEach-Object {$isMicrosoft $false$signerInfo 无可执行路径if ($_.PathName) {# 提取可执行文件路径&#xff08;处理带引号/参数的路径&#xff09…

小程序难调的组件

背景。做小程序用到了自定义表单。前后端都是分开写的&#xff0c;没有使用web-view。所以要做到功能对称时间选择器。需要区分datetime, year, day等类型使用uview组件较方便 <template><view class"u-date-picker" v-if"visible"><view c…

从零构建TransformerP2-新闻分类Demo

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录引言1 一个完整的Transformer模型2 需要准备的“工…

qt qml实现电话簿 通讯录

qml实现电话簿&#xff0c;基于github上开源代码修改而来&#xff0c;增加了搜索和展开&#xff0c;效果如下 代码如下 #include <QGuiApplication> #include <QQmlApplicationEngine>int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_…

顺序表——C语言

顺序表实现代码解析与学习笔记一、顺序表基础概念顺序表是线性表的一种顺序存储结构&#xff0c;它使用一段连续的内存空间&#xff08;数组&#xff09;存储数据元素&#xff0c;通过下标直接访问元素&#xff0c;具有随机访问的特性。其核心特点是&#xff1a;元素在内存中连…

【Oracle篇】Oracle Data Pump远程备份技术:直接从远端数据库备份至本地环境

&#x1f4ab;《博主主页》&#xff1a;    &#x1f50e; CSDN主页__奈斯DB    &#x1f50e; IF Club社区主页__奈斯、 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对…

Linux系统--文件系统

大家好&#xff0c;我们今天继续来学习Linux系统部分。上一次我们学习了内存级的文件&#xff0c;下面我们来学习磁盘级的文件。那么话不多说&#xff0c;我们开始今天的学习&#xff1a; 目录 Ext系列⽂件系统 1. 理解硬件 1-1 磁盘、服务器、机柜、机房 1-2 磁盘物理结构…

KUKA库卡焊接机器人氩气节气设备

在焊接生产过程中&#xff0c;氩气作为一种重要的保护气体被广泛应用于KUKA库卡焊接机器人的焊接操作中。氩气的消耗往往是企业生产成本的一个重要组成部分&#xff0c;因此实现库卡焊接机器人节气具有重要的经济和环保意义。WGFACS节气装置的出现为解决这一问题提供了有效的方…

远程连接----ubuntu ,rocky 等Linux系统,WindTerm_2.7.0

新一代开源免费的终端工具-WindTerm github 27.5k⭐ https://github.com/kingToolbox/WindTerm/releases/download/2.7.0/WindTerm_2.7.0_Windows_Portable_x86_64.zip 主机填写你自己要连接的主机ip 端口默认 22 改成你ssh文件配置的端口 输入远程的 用户名 与密码 成功连接…

笔试——Day32

文章目录第一题题目思路代码第二题题目&#xff1a;思路代码第三题题目&#xff1a;思路代码第一题 题目 素数回文 思路 模拟 构建新的数字&#xff0c;判断该数是否为素数 代码 第二题 题目&#xff1a; 活动安排 思路 区间问题的贪⼼&#xff1a;排序&#xff0c;然…

超高车辆如何影响城市立交隧道安全?预警系统如何应对?

超高车辆对立交隧道安全的潜在威胁在城市立交和隧道中&#xff0c;限高设施的设计通常考虑到大部分正常通行的货车和运输车辆。然而&#xff0c;一些超高的货车、集装箱车或特殊车辆如果未经有效监测而进入限高区域&#xff0c;就可能对道路设施造成极大的安全隐患。尤其在立交…

解决 MinIO 上传文件时报 S3 API Requests must be made to API port错误

在使用 MinIO 进行文件上传时&#xff0c;我遇到了一个比较坑的问题。错误日志如下&#xff1a; io.minio.errors.InvalidResponseException: Non-XML response from server. Response code: 400, Content-Type: text/xml; charsetutf-8, body: <?xml version"1.0&quo…

linux_https,udp,tcp协议(更新中)

目录 https 加密类型 对称加密 非对称加密 加密方案 只用对程加密 只用非对程加密 双方都是用非对程加密 非对称对称加密 非对称对称加密证书 流程图 校验流程图 udp udp协议格式 特点 UDP缓冲区 tcp tcp协议格式 32位序号及确认序号 4位首部 6位标志位 1…

web端-登录页面验证码的实现(springboot+vue前后端分离)超详细

目录 一、项目技术栈 二、实现效果图 ​三、实现路线 四、验证码的实现步骤 五、完整代码 1.前端 2.后端 一、项目技术栈 登录页面暂时涉及到的技术栈如下: 前端 Vue2 Element UI Axios&#xff0c;后端 Spring Boot 2 MyBatis MySQL JWT Maven 二、实现效果图…