【数据结构】——顺序表(增删查改)

 

目录

 前言:

顺序表: 

1、概念及分类 

1.1顺序表分类

静态顺序表

动态顺序表

 2、接口实现

2.1功能要求

2.2功能实现 

💡初始化顺序表

 💡销毁顺序表

 💡顺序表尾插入

💡检查是否扩容 

💡打印顺序表 

 💡顺序表头插入

💡顺序表头删除

💡顺序表尾删除

💡顺序表pos位置插入值

 💡顺序表删除pos的位置

 总代码

test.c

 SeqList.c

 SeqList.h


 

 前言:

数据结构是计算机存储、组织数据的方式。 

数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。

能够存储数据(如顺序表、链表等结构)
存储的数据能够方便查找

顺序表: 

数据结构分为:线性表非线性表

        顺序表就是线性表中的一个小类。

何为线性表:线性表是指n个具有相同性质的数据元素的有限序列,

        常见的线性表有:顺序表、链表、栈、队列、字符串等等

注:线性表的物理结构不一定是线性的,它在逻辑结构上一定是线性的(这个很好理解,等我们学完顺序表和单链表这对黄金搭档,就明白这句话的含义了。(逻辑结构类似于想象的,比如箭头这种东西在内存中是存在的))

顺序表是线性表,顺序表在逻辑结构和物理结构上都是线性的。 

 

1、概念及分类 

顺序表(SeqList):顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构连续存储数据,不能跳跃)。 

类似于数组,但是顺序表是连续的(只能从头开始连续),数组不需要连续;

1.1顺序表分类

静态顺序表

概念:使用定长数组存储元素

缺陷:空间给少了不够⽤,给多了造成空间浪费

//静态顺序表
typedef int SLDataType;
#define N 7
struct SeqList
{SLDataType arr[N];  //定长数组int size;       //有效数据个数
}SL;

 

动态顺序表

概念:使用动态开辟的数组存储。 

//动态顺序表
typedef int SLDateType;
typedef struct SeqList
{SLDateType* array;  //指向动态开辟的数组size_t size;  //数据中存储的数据size_t capacity;   //数组的容量
}SeqList;

 

建议用动态顺序表,比起静态顺序表,动态的更加好调整顺序表的大小。接下来,我也会以动态顺序表为例,介绍如何实现动态顺序表的增删查改。 

 2、接口实现

2.1功能要求

#pragma once
#include<stdio.h>
#include<assert.h>//对顺序表的初始化
void SeqListInit(SL* ps);//对顺序表的销毁
void SeqListDestroy(SL* ps);//对顺序表的打印
void SeqListPrint(SL* ps);//对顺序表的尾插入
void SeqListPushBack(SL* ps, SLDataType x);//对顺序表的头插入
void SeqListPushFront(SL* ps, SLDataType x);//对顺序表头删除
void SeqListPopFront(SL* ps);//对顺序表的尾删除
void SeqListPopBack(SL* ps);// 顺序表查找
//int SeqListFind(SeqList* ps, SLDateType x);// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x);// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);

2.2功能实现 

💡初始化顺序表

没啥好说的,在【C语言】系列都讲过了,3 2 1 上链接

//初始化
void SeqListInit(SL* ps)
{assert(ps);ps->arry = NULL;ps->size = 0;ps->capacity = 0;
}
 💡销毁顺序表
//销毁
void SeqListDestroy(SL* ps)
{assert(ps);if (ps->arry != NULL){free(ps->arry);ps->arry = NULL;ps->size = 0;ps->capacity = 0;}
}
 💡顺序表尾插入

这里需要检查是否需要扩容,我们还需要提前封装一个函数

//对顺序表的尾插入
void SeqListPushBack(SL* ps, SLDataType x)
{assert(ps);//检查是否需要扩容CheckCapacity(ps);ps->arry[ps->size] = x;ps->size++;
}
💡检查是否扩容 

在这里需要注意的就是,我们初始化的时候,capacity是0,如果用常规*2方式扩容,0*2还是0;

所以这里可以用上一个三目操作符来避免;realloc可以对空指针进行开辟空间,相当于malloc

 

//检查是否需要扩容
void CheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity)	//需要扩容{int new =ps->capacity == 0 ? 4 :ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->arry, sizeof(SLDataType)*new);//检查是否扩容成功if (tmp == NULL){perror("realloc");return;}ps->arry = tmp;ps->capacity = new;printf("扩容成功\n");}
}
💡打印顺序表 
//打印顺序表
void SeqListPrint(SL* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arry[i]);}printf("\n");
}
 💡顺序表头插入

不管是头插入还是尾插入以及后面的任意位置插入,都需要检查是否需要扩容,

头插入就相当于先将数据往右边移动,头位置空出来,然后将新数据插入即可

//头插入
void SeqListPushFront(SL* ps, SLDataType x)
{assert(ps);CheckCapacity(ps);int begin = ps->size;while (begin>0){ps->arry[begin] = ps->arry[begin - 1];begin--;}ps->arry[0] = x;ps->size++;
}
💡顺序表头删除

 因为顺序表的逻辑结构和物理结构一致,数据前后紧密相连的,所以可以直接将数据往前覆盖

//头删除
void SeqListPopFront(SL* ps)
{assert(ps);int begin = 1;while (begin > 0 &&  begin < ps->size ){ps->arry[begin - 1] = ps->arry[begin];begin++;}ps->size--;
}
💡顺序表尾删除

需要注意的就说size跑到负数去,我们采取“七匹狼式警告”,直接“竹条炒肉”

//尾删除
void SeqListPopBack(SL* ps)
{assert(ps);//对size检查 防止越界assert(ps->size > 0);ps->size--;
}
💡顺序表pos位置插入值

在容量内任意位置插入,将该位置后的数据往后移,将新元素赋值

// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);CheckCapacity(ps);int begin = ps->size;while (begin > pos){ps->arry[begin] = ps->arry[begin - 1];begin--;}ps->arry[pos] = x;ps->size++;
}
 💡顺序表删除pos的位置
// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);int begin = pos;while (begin < ps->size){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;
}

 总代码

注意,我们完成每个功能实现,最好都单独测试一下,不要留到最后,不然就会这样

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//11-4ݽṹ
#include<stdio.h>void test1()
{SL s1;SeqListInit(&s1);SeqListPushBack(&s1,1);SeqListPrint(&s1);SeqListDestroy(&s1);
}void test2()
{SL s2;SeqListInit(&s2);SeqListPushBack(&s2, 1);SeqListPushBack(&s2, 2);SeqListPushBack(&s2, 3);SeqListPushBack(&s2, 4);SeqListPushBack(&s2, 5);SeqListPushFront(&s2,10);SeqListPrint(&s2);}//void test3()
//{
//	SL s3;
//	SeqListInit(&s3);
//	SeqListPushBack(&s3, 1);
//	SeqListPushBack(&s3, 2);
//	SeqListPushBack(&s3, 3);
//	SeqListPushBack(&s3, 4);
//	SeqListPushBack(&s3, 5);
//	SeqListPrint(&s3);
//
//	SeqListPopFront(&s3);
//	SeqListPrint(&s3);
//}void test4()
{SL s4;SeqListInit(&s4);SeqListPushBack(&s4, 1);SeqListPushBack(&s4, 2);SeqListPushBack(&s4, 3);SeqListPushBack(&s4, 4);SeqListPushBack(&s4, 5);SeqListPrint(&s4);SeqListInsert(&s4, 2, 66);SeqListPrint(&s4);
}
void test5()
{SL s5;SeqListInit(&s5);SeqListPushBack(&s5, 1);SeqListPushBack(&s5, 2);SeqListPushBack(&s5, 3);SeqListPushBack(&s5, 4);SeqListPushBack(&s5, 5);SeqListPrint(&s5);SeqListErase(&s5, 2);SeqListPrint(&s5);
}
int main()
{ //test1();//test2();//test3();//test4();test5();return 0;
}

 SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//初始化
void SeqListInit(SL* ps)
{assert(ps);ps->arry = NULL;ps->size = 0;ps->capacity = 0;
}
//销毁
void SeqListDestroy(SL* ps)
{assert(ps);if (ps->arry != NULL){free(ps->arry);ps->arry = NULL;ps->size = 0;ps->capacity = 0;}
}
//检查是否需要扩容
void CheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity)	//需要扩容{int new =ps->capacity == 0 ? 4 :ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->arry, sizeof(SLDataType)*new);//检查是否扩容成功if (tmp == NULL){perror("realloc");return;}ps->arry = tmp;ps->capacity = new;printf("扩容成功\n");}}
//对顺序表的尾插入
void SeqListPushBack(SL* ps, SLDataType x)
{assert(ps);//检查是否需要扩容CheckCapacity(ps);ps->arry[ps->size] = x;ps->size++;
}
//打印顺序表
void SeqListPrint(SL* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arry[i]);}printf("\n");
}
//头插入
void SeqListPushFront(SL* ps, SLDataType x)
{assert(ps);CheckCapacity(ps);int begin = ps->size;while (begin>0){ps->arry[begin] = ps->arry[begin - 1];begin--;}ps->arry[0] = x;ps->size++;
}
//头删除
void SeqListPopFront(SL* ps)
{assert(ps);int begin = 1;while (begin > 0 &&  begin < ps->size ){ps->arry[begin - 1] = ps->arry[begin];begin++;}ps->size--;
}
//尾删除
void SeqListPopBack(SL* ps)
{assert(ps);//对size检查 防止越界assert(ps->size > 0);ps->size--;
}// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);CheckCapacity(ps);int begin = ps->size;while (begin > pos){ps->arry[begin] = ps->arry[begin - 1];begin--;}ps->arry[pos] = x;ps->size++;
}// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);int begin = pos;while (begin < ps->size){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;

 SeqList.h

#pragma once
#include<stdio.h>
#include<assert.h>
typedef int SLDataType;typedef struct SeqList
{SLDataType* arry;	//动态开辟的数组int size;	//记录个数int capacity;	//记录容量
}SL;//对顺序表的初始化
void SeqListInit(SL* ps);//对顺序表的销毁
void SeqListDestroy(SL* ps);//对顺序表的打印
void SeqListPrint(SL* ps);//对顺序表的尾插入
void SeqListPushBack(SL* ps, SLDataType x);//对顺序表的头插入
void SeqListPushFront(SL* ps, SLDataType x);//对顺序表头删除
void SeqListPopFront(SL* ps);//对顺序表的尾删除
void SeqListPopBack(SL* ps);// 顺序表查找
//int SeqListFind(SeqList* ps, SLDateType x);// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x);// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);

 

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

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

相关文章

【二进制转换和与其有关的操作符详解】

文章目录 1.二进制与进制转换2. 2进制转8、10、16进制2.1 2进制转10进制2.2 2进制转8进制2.3 2进制转16进制 3. 8、10、16进制转2进制3.1 10进制转2进制3.2 8进制转2进制3.3 16进制转2进制 4.原码、反码、补码5.移位操作符&#xff08;<< >>&#xff09;5.1左移操作…

【IDEA】在工具栏设置快速创建包和类的图表

页面效果&#xff1a; 操作步骤&#xff1a; 设置 --> 外观与行为 --> 菜单与工具栏 --> 点击 主工具栏 --> 点击 ---- --> 点击 号 --> 添加操作 主菜单 --> 文件 --> 文件打开操作 --> 打开项目操作 --> 新建 --> 往下找 找到 clas…

超声波俱乐部分享:百度世界大会点燃AI创业者新希望

10月22日&#xff0c;2023年第十三期超声波俱乐部内部分享会在北京望京举行。本期的主题是&#xff1a;百度世界大会点燃AI创业者新希望。 到场的嘉宾有&#xff1a;超声波创始人杨子超&#xff0c;超声波联合创始人、和牛商业创始人刘思雨&#xff0c;中国国际经济交流中心研…

开启AWS的ubuntu服务器的root用户登录权限

设置root用户密码 输入以下命令修改root用户密码 sudo passwd root输入以下命令切换到root用户 su root仅允许root用户用密码登录 输入以下命令编辑ssh配置文件 vi /etc/ssh/sshd_config新增以下配置允许root用户登录 PermitRootLogin yes把PasswordAuthentication修改为…

成员变量为动态数据时不可轻易使用

问题描述 业务验收阶段&#xff0c;遇到了一个由于成员变量导致的线程问题 有一个kafka切面&#xff0c;用来处理某些功能在调用前后的发送消息&#xff0c;资产类型type是成员变量定义&#xff1b; 资产1类型推送消息是以zichan1为节点&#xff1b;资产2类型推送消息是以zi…

2023-11-06今日最大收获:坑爹的 JpaRepository!

1.坑爹的 JpaRepository&#xff01; org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet 2023-11-06 18:38:53.12…

报错Could not resolve placeholder ‘driver‘ in value “${driver}“

这是我的报错&#xff1a; 原因是我的applicationContext.xml文件加载properties文件径错误&#xff1a; 应该把路径改成这样就可以了&#xff1a;

ansible安装和常见模块

文章目录 ansible的安装1.1 yum install epel-release.noarch1.2配置epel源的baseurl1.3安装ansible1.4安装ansible报错问题1.5 yum卸载 ansible的安装 ansible是由epel源提供的&#xff0c;所以需要配置epel源。要么通过配置好的baseos源直接执行“yum install epel-release.…

数据分析案例-基于服饰行业中消费者行为和购物习惯的可视化分析(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

JavaScript设计模式之发布-订阅模式

发布者和订阅者完全解耦&#xff08;通过消息队列进行通信&#xff09; 适用场景&#xff1a;功能模块间进行通信&#xff0c;如Vue的事件总线。 ES6实现方式&#xff1a; class eventManager {constructor() {this.eventList {};}on(eventName, callback) {if (this.eventL…

微型导轨在医疗设备中起什么作用?

微型导轨因其高精度、小型化和轻量化的特点&#xff0c;被广泛应用于各种需要高精度和小型化的机器中&#xff0c;如数控机床、工业机器人、光学仪器、医疗设备和自动化设备等&#xff0c;尤其是医疗领域&#xff0c;其应用最为广泛。 1、手术机器人&#xff1a;手术机器人是医…

虚拟列表方案实现

虚拟列表 长列表优化的2种思路&#xff1a; 分片渲染只渲染可视区域 基本概念 进程&#xff1a;这个概念比较大。每开一个应用程序都会分配一个独立的进程&#xff0c;等于每个应用都是一个进程(当然也有一个应用有很多进程)&#xff0c;进程是一个更大的概念&#xff0c;一个进…

干货丨Linux终端常见用法总结(收藏)

一、前言 熟悉Linux终端的基础用法和常见技巧可以极大提高运维及开发人员的工作效率&#xff0c;笔者结合自身学习实践&#xff0c;总结以下终端用法供同行交流学习。 二、常见用法 1.快捷键 1.1.Alt. 在光标位置插入上一次执行命令的最后一个参数。 1.2.CtrlR 模糊搜索历…

计讯物联高精度GNSS接收机:担当小型水库大坝安全监测解决方案的“护航者”

应用背景 水库大坝作为水利工程建筑物&#xff0c;承担着灌溉、发电、供水、生态等重任。一旦水库大坝发生安全事故&#xff0c;后果将不堪设想。因此&#xff0c;水库大坝的安全监测对保障水利工程顺利运行具有重要意义。 计讯物联作为水利行业专家型企业&#xff0c;多年来…

mysql之备份和恢复

&#xff08;一&#xff09;备份 1、备份的种类 &#xff08;1&#xff09;完全备份&#xff1a;将整个数据库完整的进行备份 &#xff08;2&#xff09;增量备份&#xff1a;在完全备份的基础上&#xff0c;对后续新增的内容进行备份 2、备份的需求 &#xff08;1&#x…

[pytorch]手动构建一个神经网络并且训练

0.写在前面 上一篇博客全都是说明类型的,实际代码能不能跑起来两说,谨慎观看.本文中直接使用fashions数据实现softmax的简单训练并且完成结果输出.实现一个预测并且观测到输出结果. 并且更重要的是,在这里对一些训练的过程,数据的形式,以及我们在softmax中主要做什么以及怎么…

Spring Boot中解决跨域问题(CORS)

1. 跨域介绍 首先解释什么是跨域&#xff0c;跨域就是前端和后端的端口号不同&#xff1b;会产生跨域问题&#xff0c;这里浏览器的保护机制&#xff08;同源策略&#xff09;。 同源策略&#xff1a;前端和后端的协议、域名、端口号三者都相同叫做同源。 我们看一下不同源&am…

【k8s】pod调度——亲和,反亲和,污点,容忍

官方网址&#xff1a;https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/ 一、亲和性 &#xff08;1&#xff09;节点亲和性 pod.spec.nodeAffinity ●preferredDuringSchedulingIgnoredDuringExecution&#xff1a;软策略 p开头 ●requiredDuri…

【ARM AMBA AXI 入门 12 -- AXI协议中的 WLAST 与 RLAST】

文章目录 AXI协议中的 WLAST 与 RLAST AXI协议中的 WLAST 与 RLAST AMBA AXI协议是由ARM公司定义的一种高性能&#xff0c;高频率的总线协议。总线协议中的 WLAST 信号是一个重要的信号&#xff0c;它在 AXI 协议中用来标识一个突发&#xff08;Burst&#xff09;传输的最后一…

Azure 机器学习 - 使用 ONNX 对来自 AutoML 的计算机视觉模型进行预测

目录 一、环境准备二、下载 ONNX 模型文件2.1 Azure 机器学习工作室2.2 Azure 机器学习 Python SDK2.3 生成模型进行批量评分多类图像分类 三、加载标签和 ONNX 模型文件四、获取 ONNX 模型的预期输入和输出详细信息ONNX 模型的预期输入和输出格式多类图像分类 多类图像分类输入…