顺序表的实现(头插、尾插、头删、尾删、查找、删除、插入)

目录

一. 数据结构相关概念​

二、线性表 

三、顺序表概念及结构 

3.1顺序表一般可以分为:

3.2 接口实现: 

四、基本操作实现

4.1顺序表初始化

4.2检查空间,如果满了,进行增容​编辑

4.3顺序表打印

4.4顺序表销毁

4.5顺序表尾插

4.6顺序表头插

4.7顺序表头删

4.8顺序表尾删

4.9顺序表在pos位置插入x

4.10顺序表删除pos位置的值


链表相关知识:

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)-CSDN博客

链表基础知识(一、单链表、头插、尾插、头删、尾删、查找、删除、插入)-CSDN博客

一. 数据结构相关概念​

什么是数据结构​?

数据结构是由“数据”和“结构”两词组合而来。
什么是数据?常见的数值1、2、3、4.....、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据什么是结构?
当我们想要使用大量使用同一类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。

概念:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系
的数据元素的集合
。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。
总结:
1)能够存储数据(如顺序表、链表等结构)​
2)存储的数据能够方便查找​
2、为什么需要数据结构?​

通过数据结构,能够有效将数据组织和管理在一起。按照我们的方式任意对数据进行增删改查等操
作。
最基础的数据结构:数组。

【思考】有了数组,为什么还要学习其他的数据结构?
假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:​
求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是
否要判断数组是否满了,满了还能继续插入吗).....​
假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。
结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。
 

二、线性表 

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

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

三、顺序表概念及结构 

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

  • 顺序表和数组的区别

  • 顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口

3.1顺序表一般可以分为:

  • 静态顺序表:使用定长数组存储。

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

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

// 顺序表的动态存储
typedef struct SeqList
2.2 接口实现: 
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大
了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态
的分配空间大小,所以下面我们实现动态顺序表。
{SLDataType* array;  // 指向动态开辟的数组size_t size ;       // 有效数据个数size_t capicity ;   // 容量空间的大小
}SeqList;

3.2 接口实现: 

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

先解释一下预处理指令

  • #pragma once:这是一个非标准的预处理指令,它告诉预处理器这个头文件只应该被包含一次。如果尝试多次包含,预处理器会忽略后续的包含。尽管它是非标准的,但许多现代编译器(如GCC和Clang)都支持它。

  • #ifndef SEQLIST_H:这是一个条件编译指令。它检查是否定义了一个名为SEQLIST_H的宏。如果没有定义(即这个头文件还没有被包含过),那么接下来的代码会被编译。

  • #define SEQLIST_H:这定义了一个名为SEQLIST_H的宏。当这个头文件首次被包含时,这个宏会被定义,从而标记这个头文件已经被包含过了。

  • #endif:这结束了之前的#ifndef条件编译块。

SeqList.h

//#pragma once
#ifndef _SEQLIST_H_
#define _SEQLIST_H_#include<stdio.h>
#include<string.h>
#include<stdlib.h>#include<assert.h>//增强程序的可维护性
#define MAX_SIZE 10
typedef int SQDataType;
//静态顺序表
//问题:给少了不够用,给多了用不完浪费,不能灵活控制//typedef struct SeqList
//{
//	SQDataType a[MAX_SIZE];
//	int size;
//}SL;typedef struct SeqList
{SQDataType *a;// 指向动态开辟的数组int size;	 //有效的数据的个数int capacity;//容量
}SL;//typedef struct SeqList SL;//定义为简写// 基本增删查改接口
// 顺序表初始化//增删查改等接口函数
//void SeqListInit(struct SeqList s);//顺序表初始化
void SeqListInint(SL* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList * psl);
//顺序表打印
void SeqListPrint(SL* ps);
// 顺序表销毁
void SeqListDestory(SL* ps);
//顺序表尾插
void SeqListPushBack(SL* ps, SQDataType x);
//顺序表头插
void SeqListPushFront(SL* ps, SQDataType x);
//顺序表头删
void SeqListPopBack(SL* ps);
//顺序表尾删
void SeqListPopFront(SL* ps);// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SQDataType x);// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);#endif

四、基本操作实现

4.1顺序表初始化

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

4.2检查空间,如果满了,进行增容

 这个函数的主要目的是在顺序列表满时自动扩容,以便能够继续添加元素。它首先检查列表是否已满,然后计算新的容量,并使用realloc函数尝试调整数组的大小。如果realloc失败(返回NULL),则打印错误信息并退出程序。如果成功,就更新列表的数组指针和容量。

// 函数定义,传入一个指向顺序列表(SeqList)的指针  
void SeqListCheckCapacity(SL* ps)  
{  // 检查顺序列表是否已满,即当前大小(size)是否等于容量(capacity)  if (ps->size == ps->capacity)  {  // 如果满了,计算新的容量。如果当前容量为0,则新容量为4;否则,新容量为当前容量的2倍  int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;  // 使用realloc函数尝试调整顺序列表的数组大小  // realloc可能会改变原有内存块的位置,因此需要使用一个临时指针来接收结果  SQDataType* tmp = (SQDataType*)realloc(ps->a, newcapacity * sizeof(SQDataType));  // 检查realloc是否成功  if (tmp == NULL)  {  // 如果失败,打印错误信息并退出程序  printf("realloc fail\n");  exit(-1);  }  else  {  // 如果成功,更新顺序列表的数组指针和容量  ps->a = tmp;  ps->capacity = newcapacity;  }  }  
}

4.3顺序表打印

这个函数的主要目的是遍历顺序列表,并打印出其中的每一个元素。通过循环,它会依次访问列表中的每个元素,并将其打印。

// 打印顺序列表中的所有元素  
void SeqListPrint(SL* ps)  
{  // 通过循环遍历顺序列表中的每一个元素  for (int i = 0; i < ps->size; i++)  {  printf("%d ", ps->a[i]);  }  // 打印一个换行符,使得每次打印列表后都会换行,输出更清晰  printf("\n");  
}

4.4顺序表销毁

 SeqListDestroy函数主要目的是释放顺序列表所占用的内存空间

// 销毁顺序列表的函数  
void SeqListDestroy(SL* ps)  
{  // 断言:确保传入的顺序列表指针ps不为空  assert(ps);  // 判断顺序列表的数组指针a是否不为空  if (ps->a != NULL)  {  // 释放数组指针a所指向的内存空间  free(ps->a);  // 将数组指针a设置为NULL,避免野指针  ps->a = NULL;  // 将顺序列表的大小设置为0,表示列表已空  ps->size = 0;  // 将顺序列表的容量设置为0,表示已没有分配内存空间  ps->capacity = 0;  }  
}

4.5顺序表尾插

在插入新元素之前,它们都首先检查当前的容量是否足够,如果不够则调用 SeqListCheckCapacity 函数进行扩容。尾插函数SeqListPushBack直接在末尾添加新元素

// 尾插法:在顺序列表的末尾插入一个新元素  
void SeqListPushBack(SL* ps, SQDataType x)  
{  // 检查当前顺序列表的容量是否足够,如果不够则进行扩容  SeqListCheckCapacity(ps);  // 在顺序列表的当前末尾位置插入新元素  ps->a[ps->size] = x;  // 更新顺序列表的大小(元素数量)  ps->size++;  
}  

4.6顺序表头插

在插入新元素之前,它们都首先检查当前的容量是否足够,如果不够则调用 SeqListCheckCapacity 函数进行扩容。头插函数SeqListPushFront将现有元素向后移动以腾出空间。

// 头插法:在顺序列表的开头插入一个新元素  
void SeqListPushFront(SL* ps, SQDataType 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++;  
}

4.7顺序表头删

 SeqListPopFront`函数用于删除顺序列表的第一个元素。它首先通过断言确保列表不为空,然后通过一个循环将第一个位置之后的所有元素都向前移动一个位置,从而覆盖掉第一个位置的元素,并更新列表的大小。

// 头删:删除顺序列表的第一个元素  
void SeqListPopFront(SL* ps)  
{  // 断言,确保顺序列表不为空,即其大小大于0  // 如果ps->size <= 0,则触发断言错误,终止程序  assert(ps->size > 0);  // 初始化一个变量start,用于从第二个元素开始遍历  int start = 1;  // 当start小于列表大小时,执行循环  // 这个循环用于将第一个位置之后的元素都向前移动一个位置,从而覆盖掉第一个位置的元素  while (start < ps->size)  {  // 将下一个位置的元素移动到当前位置  ps->a[start - 1] = ps->a[start];  // start向后移动一个位置,继续处理下一个元素  start++;  }  // 因为第一个元素已经被覆盖,所以不需要额外处理  // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1  ps->size--;  
}

4.8顺序表尾删

 SeqListPopBack函数用于删除顺序列表的最后一个元素。它首先通过断言确保列表不为空,然后直接更新列表的大小。

// 尾删:删除顺序列表的最后一个元素  
void SeqListPopBack(SL* ps)  
{  // 断言,确保顺序列表不为空,即其大小大于0  // 如果ps->size <= 0,则触发断言错误,终止程序  assert(ps->size > 0);  // 可以选择将最后一个元素的值设置为0或其他默认值,以确保不留下未定义的值  // 但这取决于具体的应用需求,有时可能不需要这样做  //ps->a[ps->size - 1] = 0;  // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1  ps->size--;  
}

4.9顺序表在pos位置插入x

 SeqListInsert函数的主要作用是在顺序列表的指定位置pos插入一个新元素x。为了达到这个目的,它首先确保插入的位置是有效的(不会超出当前列表的大小),然后检查是否需要扩容。接着,它通过一个循环将pos位置及其之后的元素都向后移动一个位置,以便为新元素腾出空间。最后,它在pos位置插入新元素,并更新列表的大小。

// 在顺序列表的指定位置插入一个元素  
void SeqListInsert(SL* ps, int pos, SQDataType x)  
{  // 断言,确保插入的位置不会超出当前列表的大小  // 如果pos >= ps->size,则触发断言错误,终止程序  assert(pos < ps->size);  // 检查当前顺序列表的容量是否足够,如果不够则进行扩容  SeqListCheckCapacity(ps);  // 初始化一个变量end,用于从列表的末尾开始遍历  int end = ps->size - 1;  // 当end位置大于或等于要插入的位置pos时,执行循环  // 这个循环用于将pos位置及其之后的元素都向后移动一个位置,为插入新元素腾出空间  while (end >= pos)  {  // 将当前位置的元素向后移动一个位置  ps->a[end + 1] = ps->a[end];  // end向前移动一个位置,继续处理前一个元素  end--;  }  // 在腾出的位置pos处插入新元素x  ps->a[pos] = x;  // 更新顺序列表的大小(元素数量)  ps->size++;  
}

4.10顺序表删除pos位置的值

SeqListErase函数用于删除顺序列表中指定位置的元素。它首先通过断言确保要删除的位置是有效的,然后通过一个循环将指定位置之后的所有元素都向前移动一个位置,从而覆盖掉指定位置的元素。最后,它更新列表的大小。

// 删除顺序列表中指定位置的元素  
void SeqListErase(SL* ps, int pos)  
{  // 断言,确保要删除的位置不会超出当前列表的大小  // 如果pos >= ps->size,则触发断言错误,终止程序  assert(pos < ps->size);  // 初始化一个变量start,用于从要删除的位置的下一个元素开始遍历  int start = pos + 1;  // 当start小于列表大小时,执行循环  // 这个循环用于将pos位置之后的元素都向前移动一个位置,覆盖掉pos位置的元素  while (start < ps->size)  {  // 将下一个位置的元素移动到当前位置  ps->a[start - 1] = ps->a[start];  // start向后移动一个位置,继续处理下一个元素  start++;  }  // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1  ps->size--;  
}  

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

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

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

相关文章

Quartz持久化(springboot整合mybatis版本实现调度任务持久化)--提供源码下载

1、Quartz持久化功能概述 1、实现使用quartz提供的默认11张持久化表存储quartz相关信息。 2、实现定时任务的编辑、启动、关闭、删除。 3、实现自定义持久化表存储quartz定时任务信息。 4、本案例使用springboot整合mybatis框架和MySQL数据库实现持久化 5、提供源码下载 …

初识Stable Diffusion

界面选项解读 这是在趋动云上部署的Stable Diffusion txt2img prompt &#xff08;1&#xff09;分割符号&#xff1a;使用逗号 , 用于分割词缀&#xff0c;且有一定权重排序功能&#xff0c;逗号前权重高&#xff0c;逗号后权重低 &#xff08;2&#xff09;建议的通用范式…

MyBatis见解4

10.MyBatis的动态SQL 10.5.trim标签 trim标签可以代替where标签、set标签 mapper //修改public void updateByUser2(User user);<update id"updateByUser2" parameterType"User">update user<!-- 增加SET前缀&#xff0c;忽略&#xff0c;后缀…

计算机网络复习-OSI TCP/IP 物理层

我膨胀了&#xff0c;挂我啊~ 作者简介&#xff1a; 每年都吐槽吉师网安奇怪的课程安排、全校正经学网络安全不超20人情景以及割韭菜企业合作的FW&#xff0c;今年是第一年。。 TCP/IP模型 先做两道题&#xff1a; TCP/IP协议模型由高层到低层分为哪几层&#xff1a; 这题…

VScode远程连接服务器,Pycharm专业版下载及远程连接(深度学习远程篇)

Visual Code、PyCharm专业版&#xff0c;本地和远程交互。 远程连接需要用到SSH协议的技术&#xff0c;常用的代码编辑器vscode 和 pycharm都有此类功能。社区版的pycharm是免费的&#xff0c;但是社区版不支持ssh连接服务器&#xff0c;只有专业版才可以&#xff0c;需要破解…

C# 读取Word表格到DataSet

目录 功能需求 Office 数据源的一些映射关系 范例运行环境 配置Office DCOM 关键代码 组件库引入 ​核心代码 杀掉进程 总结 功能需求 在应用项目里&#xff0c;多数情况下我们会遇到导入 Excel 文件数据到数据库的功能需求&#xff0c;但某些情况下&#xff0c;也存…

RasaGPT对话系统的工作原理

RasaGPT 结合了 Rasa 和 Langchain 这 2 个开源项目&#xff0c;当超出 Rasa 现有意图(out_of_scope)的时候&#xff0c;就会执行 ActionGPTFallback&#xff0c;本质上就是利用 Langchain 做了一个 RAG&#xff0c;调用 LLM API。RasaGPT 涉及的技术栈比较多而复杂&#xff0c…

js显示前七天的日期,前几天依次类推

1.效果图 2.js代码 function beforetime1() {let now new Date();//想获取前七天日期就减七&#xff0c;前六天就减六&#xff0c;以此类推var date new Date(now.getTime() - 7 * 24 * 3600 * 1000);var y date.getFullYear();var m date.getMonth() 1;m m < 10 ? …

【物联网】光影之谜:RGB-LED传感器引领科技变革之路

​​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《物联网实战 | 数字奇迹记》⏰翰墨致赠&#xff1a;狂风挟雷霆舞苍穹&#xff0c;剑气横扫万里空。英雄豪情铸不朽&#xff0c;激荡壮志燃热风。 ​ 目录 ⛳️1. 初识物联网 ⛳…

TikTok与环保:短视频如何引领可持续生活方式?

在数字时代&#xff0c;社交媒体平台扮演着塑造文化和价值观的关键角色。而TikTok&#xff0c;作为一款全球短视频平台&#xff0c;不仅塑造着用户的娱乐方式&#xff0c;还在悄然地引领着可持续生活方式的潮流。本文将深入探讨TikTok与环保之间的关系&#xff0c;分析短视频如…

【FPGA】分享一些FPGA高速信号处理相关的书籍

在做FPGA工程师的这些年&#xff0c;买过好多书&#xff0c;也看过好多书&#xff0c;分享一下。 后续会慢慢的补充书评。 【FPGA】分享一些FPGA入门学习的书籍【FPGA】分享一些FPGA协同MATLAB开发的书籍 【FPGA】分享一些FPGA视频图像处理相关的书籍 【FPGA】分享一些FPGA高速…

顺序表的基本操作(必学)

目录 线性表&#xff1a; 顺序表&#xff1a; 概念和结构&#xff1a; 动态顺序表常用操作实现&#xff1a; 头文件&#xff08;数组顺序表的声明&#xff09;&#xff1a; 各种基本操作总的声明&#xff1a; 顺序表的初始化&#xff1a; 顺序表的销毁 顺序表的打印 …

【Vue2+3入门到实战】(4)Vue基础之指令修饰符 、v-bind对样式增强的操作、v-model应用于其他表单元素 详细示例

目录 一、今日学习目标1.指令补充 二、指令修饰符1.什么是指令修饰符&#xff1f;2.按键修饰符3.v-model修饰符4.事件修饰符 三、v-bind对样式控制的增强-操作class1.语法&#xff1a;2.对象语法3.数组语法4.代码练习 四、京东秒杀-tab栏切换导航高亮1.需求&#xff1a;2.准备代…

大数据深度解析NLP文本摘要技术:定义、应用与PyTorch实战

文章目录 大数据深度解析NLP文本摘要技术&#xff1a;定义、应用与PyTorch实战1. 概述1.1 什么是文本摘要&#xff1f;1.2 为什么需要文本摘要&#xff1f; 2. 发展历程2.1 早期技术2.2 统计方法的崛起2.3 深度学习的应用2.4 文本摘要的演变趋势 3. 主要任务3.1 单文档摘要3.2 …

2023年国赛高教杯数学建模E题黄河水沙监测数据分析解题全过程文档及程序

2023年国赛高教杯数学建模 E题 黄河水沙监测数据分析 原题再现 黄河是中华民族的母亲河。研究黄河水沙通量的变化规律对沿黄流域的环境治理、气候变化和人民生活的影响&#xff0c;以及对优化黄河流域水资源分配、协调人地关系、调水调沙、防洪减灾等方面都具有重要的理论指导…

mmdetection使用projects/gradio_demo

我用google的colab搭建。 # Check nvcc version !nvcc -V # Check GCC version !gcc --version # install dependencies: (use cu111 because colab has CUDA 11.1) %pip install -U openmim !mim install "mmengine>0.7.0" !mim install "mmcv>2.0.0rc4…

智能优化算法应用:基于蜣螂算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蜣螂算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蜣螂算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蜣螂算法4.实验参数设定5.算法结果6.参考文献7.MA…

WPS复选框里打对号,显示小太阳或粗黑圆圈的问题解决方法

问题描述 WPS是时下最流行的字处理软件之一&#xff0c;是目前唯一可以和微软office办公套件相抗衡的国产软件。然而&#xff0c;在使用WPS的过程中也会出现一些莫名其妙的错误&#xff0c;如利用WPS打开docx文件时&#xff0c;如果文件包含复选框&#xff0c;经常会出…

民富购:塑造数字时代下的电商革新与社会责任典范

在数字经济时代,电子商务已经成为建立市场关系、创新产业和服务业态、促进经济增长的重要途径和手段。特别是在中国,新型电子商务的迅猛发展已经改变了生产和生活的方方面面,不仅催生了众多新业态,还通过“互联网”战略让许多传统产业和服务焕发了新的生机。民富购,作为扬羊(广…

【数据结构入门精讲 | 第十七篇】一文讲清图及各类图算法

在上一篇中我们进行了的并查集相关练习&#xff0c;在这一篇中我们将学习图的知识点。 目录 概念深度优先DFS伪代码 广度优先BFS伪代码 最短路径算法&#xff08;Dijkstra&#xff09;伪代码 Floyd算法拓扑排序逆拓扑排序 概念 下面介绍几种在对图操作时常用的算法。 深度优先D…