数据结构顺序表

在这里插入图片描述
今天主要讲解顺序表,实现顺序表的尾插,头插,头删,还有尾删等操作,和我们之前写的通讯录的增删查改有类似的功能。接下来让我们开始我们的学习吧。
1.线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结
构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物
理上存储时,通常以数组和链式结构的形式存储

在这里插入图片描述
顺序表其实本质上和数组差不多。
2.顺序表
2.1概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组
上完成数据的增删查改。
顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。
    静态的顺序表通俗点讲就是死的,我们不能改变里面的元素,一开始是多少就是多少,不能实现我们的增删查改一些操作,所以我们写顺序表的时候基本上都是动态。
    静态顺序表的代码。
    在这里插入图片描述
typedef struct SeqList
{int arry[100];int size;
}SL

我们可以写成这样,但是如果我存储数据的个数不是100的话又要改,我们可以写成这样,在前面define一下。
在这里插入图片描述
同时我们的顺序表可能不只是int 类型的 这个时候我们就可以typedef一下,下次改的时候就方便很多。
在这里插入图片描述
但是我们说静态的顺序表存在缺陷,这个时候我们就得动态开辟空间,我们可以写一个动态顺序表。

typedef int SLDataType;
typedef struct SeqList
{SLDataType* arry;//指向顺序表开始位置int size;//个数int capacity;//空间
}SL;

这样的话我们就可以用动态开辟的方式实现了。

首先我们要初始化顺序表。

在这里插入图片描述
在这里插入图片描述
我们一开始这样写的时候,经过调试可以发现我们的s并没有初始化,在VS2022下直接会提醒你使用未初始化的变量s,这是为什么,是因为我们形参是实参的一份临时拷贝,并不能改变实参,所以我们传值不行,要传地址过去次啊可以解决。
在这里插入图片描述

#include"SeqList.h"
void SLInit(SL* ps)
{ps->arry = NULL;ps->capacity = ps->size = 0;
}
void SLtest1()
{SL s;SLInit(&s);
}int main()
{SLtest1();return 0;
}

那我们接下来初始化之后实现一个简单的尾插功能吧


void SLPushBack(SL* ps, SLDataType x)
{ps->arry[ps->size] = x;ps->size++;
}

我们一开始肯定会这样想,在末尾插入数字,那我们就在末尾找到这个位置,然后插入就行,但是这会有问题,一个原因就是如果这个数组满了,我们就不能插入,插入的化就要扩容,而我们一开始为什么要写动态顺序表的原因就是这个,除了这个原因以外,还有一个原因就是如果我们一开始放的是空指针的时候,这个是时候插入就相当于非法访问,所以我们在插入的时候要进行一下判断。那因为后面头插的时候也会遇到这样的问题,我们干脆给它写成一个函数,这样就方便我们使用。
尾插函数

void SLCheckCapacity(SL* ps)
{if (ps->capacity == ps->size){int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->arry, sizeof(SLDataType) * NewCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->arry = tmp;ps->capacity = NewCapacity;}} 

所以我们的尾插也可以写成

void SLPushBack(SL* ps, SLDataType x)
{SLCheckCapacity(ps);ps->arry[ps->size] = x;ps->size++;
}

我们为什么取得是结构体的地址,原因还是形参只是实参的一个临时拷贝,形参改变并不会改变实参

打印顺序表的函数。

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

打印函数可以传地址也可以传值,因为打印不会改变我们的内容,我们这里写的就是传址。
实现打印函数,我们其实可以在这些前面都加上assert,做好防御,因为如果传进来的是一个空指针的话,这就会,我们是没有办法进行修改的,所以在函数进来的时候都写好断言,从根本上解决问题。

接下来我们就写一个尾删,尾删就更简单了,直接–就行了,但是我们还要考虑一个问题就是里面一开始的时候有没有数字,如果这个顺序表为空就没有必要删除了。

void SLPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;}

从上面顺序表的尾删和尾插来看,其实顺序表相对来说效率还是比较快的,但是头删和头插的效率并不是特别高,我们继续接着写

头插

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->arry[end + 1] = ps->arry[end];end--;}ps->arry[0] = x;ps->size++;}

头插的时候也要进行检查 否则空间满的话,就会越界。

头删

void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);int begin = 0;while (begin < ps->size-1){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;
}

为什么要assert(ps->size > 0)是因为如果数都没有的话就不需要删了,所以就需要断言一下。

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->arry[end + 1] = ps->arry[end];end--;}ps->arry[pos] = x;ps->size++;
}

写完这个其实头插就可以改成SLInsert(SL* ps, 0, SLDataType x)尾插就可以改成SLInsert(SL* ps, ps->size-1, SLDataType x)
那我们在实现一个在pos位置进行删除的代码。

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int begin = pos;while (begin < ps->size-1){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;
}

那这样我们的每个功能基本都实现了,因为我们一开始realloc空间,所以我们现在要销毁原来的空间。

void SLDestory(SL* ps)
{if (ps->arry != NULL){free(ps->arry);ps->arry = NULL;}}

这样我们其实还可以用一个菜单来实现这写功能,和通讯录那个差不多,就设置一个菜单,这里小编就不搞了
给大家分享一下完整代码。

SeqList.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//#define N 100
//typedef int SLDataType;
//typedef struct SeqList
//{
//	int arry[N];
//	int size;
//}SL;typedef int SLDataType;
typedef struct SeqList
{SLDataType* arry;//指向顺序表开始位置int size;//个数int capacity;//空间
}SL;//初始化
void SLInit(SL* ps);//尾插
void SLPushBack(SL* ps, SLDataType x);//检查空间是否够
void SLCheckCapacity(SL* ps);void SLPrint(SL* ps);void SLPopBack(SL* ps);//头插
void SLPushFront(SL* ps, SLDataType x);//头删
void SLPopFront(SL* ps);void SLInsert(SL* ps, int pos, SLDataType x);void SLErase(SL* ps, int pos);void SLDestory(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"
void SLInit(SL* ps)
{ps->arry = NULL;ps->capacity = ps->size = 0;
}void SLCheckCapacity(SL* ps)
{assert(ps != NULL);if (ps->capacity == ps->size){int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->arry, sizeof(SLDataType) * NewCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->arry = tmp;ps->capacity = NewCapacity;}} 
void SLPushBack(SL* ps, SLDataType x)
{assert(ps != NULL);SLCheckCapacity(ps);ps->arry[ps->size] = x;ps->size++;
}void SLPrint(SL* ps)
{assert(ps != NULL);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arry[i]);}printf("\n");
}void SLPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->size--;}void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->arry[end + 1] = ps->arry[end];end--;}ps->arry[0] = x;ps->size++;}void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);int begin = 0;while (begin < ps->size-1){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;
}void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->arry[end + 1] = ps->arry[end];end--;}ps->arry[pos] = x;ps->size++;
}void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int begin = pos;while (begin < ps->size-1){ps->arry[begin] = ps->arry[begin + 1];begin++;}ps->size--;
}void SLDestory(SL* ps)
{if (ps->arry != NULL){free(ps->arry);ps->arry = NULL;}}

今天的分享就到这里了,我们下次再见!!!

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

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

相关文章

allegro中不可选时,如何对find进行可选操作

allegro出现不可选时&#xff0c;只能尝试其他单一的操作&#xff0c;但这样效率不高&#xff1b;可以通过菜单栏Display下拉菜单点击Element&#xff0c;即可实现FIND下选择需要调整的选项。

022 - STM32学习笔记 - 扩展外部SDRAM(一) - 初识SDRAM和FMC

022 - STM32学习笔记 - 扩展外部SDRAM&#xff08;一&#xff09; - 初识SDRAM和FMC 之前学习了I2C读写EEPROM和SPI读写FLASH&#xff0c;学完之后在学习一种新的存储介质–SDRAM。 一、初识SDRAM 我们知道在stm32内部是有一定大小的SRAM&#xff08;256Kb&#xff09;和FLA…

【Cartopy】库的安装和瓦片加载(天地图、高德等)

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 Cartopy基础入门 【Cartopy】库的安装和天地图瓦片加载 【Cartopy】【Cartopy】如何更好的确定边界显示 【Cartopy】【Cartopy】如何丝滑的加载Geojso…

100G光模块的应用案例分析:电信、云计算和大数据领域

100G光模块是一种高速光模块&#xff0c;由于其高速率和低延迟的特性&#xff0c;在电信、云计算和大数据领域得到了广泛的应用。在本文中&#xff0c;我们将深入探讨100G光模块在这三个领域的应用案例。 一、电信领域 在电信领域&#xff0c;100G光模块被广泛用于构建高速通…

机器学习深度学习——卷积的多输入多输出通道

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——从全连接层到卷积 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮…

4用opencv玩转图像2

opencv绘制文字和几何图形 黑色底图 显示是一张黑色图片 使用opencv画圆形 #画一个圆 cv2.circle(imgblack_img,center(400,400),radius100,color(0,0,255),thickness10) 画实心圆 只需要把thickness-1。 cv2.circle(imgblack_img,center(500,600),radius50,color(0,0,255),t…

Spark(39):Streaming DataFrame 和 Streaming DataSet 输出

目录 0. 相关文章链接 1. 输出的选项 2. 输出模式(output mode) 2.1. Append 模式(默认) 2.2. Complete 模式 2.3. Update 模式 2.4. 输出模式总结 3. 输出接收器(output sink) 3.1. file sink 3.2. kafka sink 3.2.1. 以 Streaming 方式输出数据 3.2.2. 以 batch …

R语言4_安装BayesSpace

环境Ubuntu22/20, R4.1 你可能会报错说你的R语言版本没有这个库&#xff0c;但其实不然。这是一个在Bioconductor上的库。 同时我也碰到了这个问题&#xff0c;ERROR: configuration failed for package systemfonts’等诸多类似问题&#xff0c;下面的方法可以一并解决。 第…

数据结构刷题训练——链表篇(二)

目录 前言 1.题目一&#xff1a;链表分割 1.1 思路 1.2 分析 1.3 题解 2. 题目二&#xff1a;相交链表 2.1 思路 2.2 分析 2.3 题解 3. 题目三&#xff1a;环形链表 3.1 思路 3.2 分析 3.3 题解 总结 前言 本期继续分享链表相关的OJ题目&#xff0c;在这个专栏博客…

elasticsearch简单入门语法

基本操作 创建不同的分词器 ik_smart&#xff1a; 极简分词 &#xff1b; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档&#xff08;指定文档id&#xff09;POSTlocalhost:9200/索引名称/类型名称创建文…

蝉妈妈:2023年抖音电商半年报(附下载)

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 平台流量竞争从愈发激烈变为趋于愈加缓和商家直攝总时长与观众君播总时长的总体趋势并没有愈加激烈&#xff0c;从23年上半年各自流量的同比增速来看&#xff0c;观众看摄总时长增速高于商家直攝总时…

电脑合上盖子无线网络不会断开

控制面板\硬件和声音\电源选项\系统设置 最终选择不会采取任何操作 选择不会采取任何操作

Cocos Creator的 Cannot read property ‘applyForce‘ of undefined报错

序&#xff1a; 1、博主是看了这个教程操作的时候出的bug>游戏开发 | 17节课学会如何用Cocos Creator制作3D跑酷游戏 | P9 代码控制对象移动_哔哩哔哩_bilibili 2、其实问题不是出在代码上&#xff0c;但是发现物体就是不平移 3、node全栈的资料》node全栈框架 正文…

逆向破解学习-雷电星海战歌

apk 雷电星海战歌 https://download.csdn.net/download/AdrianAndroid/88200826 安装apk&#xff0c;并试玩 # 通过关键字搜索jad 找到统一支付接口 找到匿名内部类的名称 Hook代码 public class HookComAstPlane extends HookImpl {Overridepublic String packageNam…

竞赛项目 深度学习手势识别算法实现 - opencv python

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习手势识别算法实现 - opencv python 该项目较为新颖…

LeetCode 31题:下一个排列

目录 题目 思路 代码 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序…

Jenkins 中 shell 脚本执行失败却不自行退出

Jenkins 中 执行 shell 脚本时&#xff0c;有时候 shell 执行失败了&#xff0c;或者判断结果是错误的&#xff0c;但是 Jenkins 执行完成后确提示成功 success 。 此时&#xff0c;可以通过条件判断来解决这个问题&#xff0c;让 Jenkins 强制退出并提示执行失败 failed 。 …

Nginx使用proxy_cache指令设置反向代理缓存静态资源

场景 CentOS7中解压tar包的方式安装Nginx&#xff1a; CentOS7中解压tar包的方式安装Nginx_centos7 tar文件 怎么load_霸道流氓气质的博客-CSDN博客 参考上面流程实现搭建Nginx的基础上&#xff0c;实现静态资源的缓存设置。 注意上面安装时的目录是在/opt/nginx目录下&…

win10 + VS2022 安装opencv C++

最近需要用到C opencv&#xff0c;看了很多帖子都需要自己编译opencv源码。为避免源码编译&#xff0c;可以使用VS来配置opencv C。下面是主要过程&#xff1a; 目录 1. 从官网下载 opencv - Get Started - OpenCV 2. 点击这个exe文件进行安装 3. 配置环境变量 4. VS中的项…

java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 tbms

​ 项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以…