拿捏 顺序表(1)

news2024/9/9 4:56:02

目录

  • 1. 顺序表的分类
  • 2. 顺序表实现
  • 3. 顺序表实现完整代码
  • 4. 总结

前言:
一天xxx想存储一组数据, 并且能够轻松的实现删除和增加, 此时数组大胆站出, 但是每次都需要遍历一遍数组, 来确定已经存储的元素个数, 太麻烦了, 于是迎来了顺序表不屑的调侃: 数组你不行啊…

顺序表是一种常见的数据结构,它是由一组连续的存储单元组成的线性表。顺序表的优点是可以随机存取,即可以通过下标直接访问元素,查找和更新操作的时间复杂度为O(1)。同时,顺序表还可以通过动态扩容来实现自动调整大小,使得其具有灵活性。本文将介绍顺序表的定义、操作以及一些应用场景,帮助读者更好地理解和应用顺序表。

博客主页: 酷酷学!!! 感谢关注❤


正文开始

1. 顺序表的分类

顺序表的底层结构就是数组,对数组的封装,实现了常用的增删改查等接,
也就是顺序表是站在数组的肩膀上飞黄腾达.

顺序表又分为静态和动态

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

在这里插入图片描述
这里有个缺陷: 空间给少了不够用, 给多了造成浪费, 于是直接pass

动态顺序表 :
在这里插入图片描述
弥补了缺陷: 就你了,下面进行实现

2. 顺序表实现

第一步:
首先完成顺序表我们分成三个源文件来完成, 这样看起来代码更舒服

在这里插入图片描述

//我们这里创建三个源文件
//Seqlist.h 用来放文件的声明已经类型的定义
//Seqlist.c 用来放顺序表实现的方法
//test.c 用来进行代码测试

第二步:
我们直接在头文件声明结构体, 并且进行一些函数的声明

//直接在.h包含头文件, 以方便我们直接使用
#pragma once//以下声明只会包含一次, 提高代码效率
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SeqDataType;//自定义类型名,方便后期修改存储数据类型

typedef struct SeqList
{
	SeqDataType* arr;
	int size;
	int capacity;
}SL;//声明结构体类型,自定义类型名为SL

void SLInit(SL* ps);//初始化函数声明
void SLDestory(SL* ps);//销毁函数声明

void SLCheckCapacity(SL* ps);//判断空间容量函数声明
void SLPushBack(SL* ps, SeqDataType x);//尾插汉书声明
void SLPushFront(SL* ps, SeqDataType x);//头插函数声明

void SLprint(SL ps);//打印内容函数

void SLPopBack(SL* ps);//尾删函数
void SLpopFront(SL* ps);//头删函数

第三步:
来到.Seqlist.c 封装各类函数

初始化:

void SLInit(SL* ps)
{
	assert(ps);//不可以给我传个NULL哦,之后每次参数为指针最好都断言一下
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

销毁操作:

void SLDestory(SL* ps)
{
	assert(ps);
	if (ps->arr)//如果arr里面有内容,那么就释放这块内存, 我们之后会动态开辟内存
	{
		free(ps->arr);
	}
	ps->arr = NULL;//避免成为野指针
	ps->capacity = ps->size = 0;
}

第四步:
前期准备工作已完成, 下面进行代码高速

首先完成怎么插入, 但是有一个问题: 如果这个顺序表大小为0, 或者大小满了的情况下我们怎么插入呢? 所以我们要进行先判断空间容量, 但是后期我们可能还要进行头插操作是不是也要判断一次, 好麻烦欸, 干脆直接封装成函数, 这样更简洁

于是乎:

void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)//没空间或者满了,这不就是需要扩容吗
	{
		int Newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//如果第一次没空间让它开辟个四块内存,不够再成倍给
		SeqDataType* tmp = (SeqDataType*)realloc(ps->arr, Newcapacity * sizeof(SeqDataType));
		//不要忘记realloc申请失败可是会返回NULL,直接赋值会造成内存泄露,不如交给临时变量
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		ps->arr = tmp;//没问题再给ps->arr
		tmp = NULL;//不需要的指针变量可以拴起来
		ps->capacity = Newcapacity;//修改空间容量大小
	}
}

第五步:实现头插尾插

先看尾插(因为比较简单)

//尾插
void SLPushBack(SL* ps, SeqDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;
}//寥寥三行,这不比数组简单?

头插:

void SLPushFront(SL* ps, SeqDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i>0; i--)
	{
		ps->arr[i] = ps->arr[i-1];//最后一次ps->arr[1] = ps->arr[0]
	}//参考下图
	ps->arr[0] = x;
	ps->size++;
}

在这里插入图片描述

我们是不是需要由左图变成右图呀, 给第一个位置空出来

第六步:
当然了, 我们也可以实验一下前面的代码正不正确,于是乎我们可以让控制台打印, 不妨写如下函数:

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

我举个栗子:
我们不妨在test.c里面写上如下代码,看看成功与否

#include "Seqlist.h"

int main()
{

	SL s;
	SLInit(&s);
	SLPushBack(&s, 4);
	SLPushBack(&s, 3);
	SLPushBack(&s, 2);
	SLPushBack(&s, 1);
	SLprint(s);

	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLprint(s);

我只能说轻松拿捏:
在这里插入图片描述

最后一步:

实现删除操作:

先来尾删(因为简单)

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}//想一想为什么这么简单,就是这么简单,因为最后那个位置直接可以被其它值覆盖

接着头删:

void SLpopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i <=ps->size-2 ; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//最后一次arr[size-2] = arr[size-1]
	}//看下图:
	ps->size--;
}

这里我们依旧需要由左边变成右边想想看是不是
在这里插入图片描述

okok,到此我们顺序表已经全部结束, 欲知后事如何,请见下回讲解,点个关注不迷路

下面直接开始今天的代码测试

#include "Seqlist.h"

int main()
{

	SL s;
	SLInit(&s);
	SLPushBack(&s, 4);
	SLPushBack(&s, 3);
	SLPushBack(&s, 2);
	SLPushBack(&s, 1);
	SLprint(s);

	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLprint(s);

	SLPopBack(&s);
	SLprint(s);

	SLpopFront(&s);
	SLprint(s);
	SLDestory(&s);
	
	return 0;
}

没有一点容错, 学废了吗
在这里插入图片描述

3. 顺序表实现完整代码

Seqlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SeqDataType;

typedef struct SeqList
{
	SeqDataType* arr;
	int size;
	int capacity;
}SL;

void SLInit(SL* ps);
void SLDestory(SL* ps);

void SLCheckCapacity(SL* ps);
void SLPushBack(SL* ps, SeqDataType x);
void SLPushFront(SL* ps, SeqDataType x);

void SLprint(SL ps);

void SLPopBack(SL* ps);
void SLpopFront(SL* ps);

Seqlist.c

#include"Seqlist.h"

void SLInit(SL* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void SLDestory(SL* ps)
{
	assert(ps);
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		int Newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SeqDataType* tmp = (SeqDataType*)realloc(ps->arr, Newcapacity * sizeof(SeqDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = Newcapacity;
	}
}

//尾插
void SLPushBack(SL* ps, SeqDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;
}

void SLPushFront(SL* ps, SeqDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i>0; i--)
	{
		ps->arr[i] = ps->arr[i-1];//最后一次ps->arr[1] = ps->arr[0]
	}
	ps->arr[0] = x;
	ps->size++;
}

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

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

void SLpopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i <=ps->size-2 ; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//arr[size-2] = arr[size-1]
	}
	ps->size--;
}

test.c

#include "Seqlist.h"

int main()
{

	SL s;
	SLInit(&s);
	SLPushBack(&s, 4);
	SLPushBack(&s, 3);
	SLPushBack(&s, 2);
	SLPushBack(&s, 1);
	SLprint(s);

	SLPushFront(&s, 3);
	SLPushFront(&s, 4);
	SLprint(s);

	SLPopBack(&s);
	SLprint(s);

	SLpopFront(&s);
	SLprint(s);
	
	SLDestory(&s);
	return 0;
}

4. 总结

顺序表是一种线性数据结构,用于存储具有相同数据类型的数据元素。它通过一片连续的存储空间来存储数据,可以按照元素的物理顺序来访问和操作。

在顺序表中,元素的存储位置是连续的,可以通过下标来访问元素。通过下标,可以快速访问和修改顺序表中的元素,这是顺序表的一个重要特点。

顺序表的插入操作比较复杂,需要将插入位置之后的所有元素后移一位,然后将新元素插入到空出的位置。删除操作也类似,需要将删除位置之后的所有元素前移一位,然后将最后一个元素删除。

顺序表的优点是存储和访问元素的效率高,可以随机访问元素。而缺点是插入和删除操作的效率相对较低,需要进行大量的数据迁移。

顺序表适用于元素数量固定且不经常变动的场景,例如存储静态的数据集合。在元素数量会经常变动的情况下,使用链表等动态数据结构更为合适。

总之,顺序表是一种经典的线性数据结构,具有高效的存储和访问性能。但在插入和删除操作上稍显不足,适用于元素数量固定且不经常变动的场景。


看完, 记得点个关注

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

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

相关文章

学习亚马逊云科技AWS云计算技术的三款官方免费3A游戏大作

玩3A大作免费电脑游戏&#xff0c;就能成为AWS云架构师、云开发大&#x1f42e;&#xff1f;这么好的事尊的假的&#xff1f;小李哥今天就来给大家介绍&#xff0c;如何通过玩AWS官方的定制版虚拟人生、炉石传说和密室逃脱游戏学习AWS。这三个游戏完全免费&#xff0c;没有任何…

react之组件与JSX

第一章 - 描述用户界面 概述&#xff1a;React是一个用于构建用户界面&#xff08;UI&#xff09;的JavaScript库&#xff0c;用户界面由按钮&#xff0c;文本和图像等小单元内容构建而成。React帮助你把它们组合成可重用&#xff0c;可嵌套的组件。从web端网站到移动端应用&a…

利用Django中的缓存系统提升Web应用性能

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在构建现代Web应用时&#xff0c;性能通常是至关重要的考虑因素之一。为了提高用户体验和应…

云原生Kubernetes: K8S 1.29版本 部署ingress-nginx

目录 一、实验 1.环境 2. K8S 1.29版本 部署ingress-nginx 二、问题 1.kubectl 如何强制删除 Pod、Namespace 资源 2.创建pod失败 3.pod报错ImagePullBackOff 4.docker如何将镜像上传到官方仓库 5.创建ingress报错 一、实验 1.环境 &#xff08;1&#xff09;主机 表…

linux 下的 sqlite数据库

SQLite 认识 SQLite简介 轻量化&#xff0c;易用的嵌入式数据库&#xff0c;用于设备端的数据管理&#xff0c;可以理解成单点的数据库。传统服务器型数据库用于管理多端设备&#xff0c;更加复杂 SQLite是一个无服务器的数据库&#xff0c;是自包含的。这也称为嵌入式数据库&…

【免费源码下载】完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城php+uniapp

简介 完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本&am…

随机游走的艺术-图嵌入表示学习

图嵌入引入 机器学习算法&#xff1a; 厨师 样本集&#xff1a; 食材 只有好的食材才能做出好的饭菜 我们需要把数据变成计算机能够读懂的形式&#xff08;将数据映射成为向量&#xff09; 图嵌入概述 传统图机器学习 图表示学习 自动学习特征&#xff0c;将…

【Linux驱动层】iTOP-RK3568学习之路(三):字符设备驱动框架

一、总体框架图 二、字符设备相关函数 静态申请设备号 register_chrdev_region 函数原型&#xff1a;register_chrdev_region(dev_t from, unsigned count, const char *name) 函数作用&#xff1a;静态申请设备号&#xff0c;可以一次性申请多个连续的号&#xff0c;count指定…

从头开始构建自己的 GPT 大型语言模型

图片来源&#xff1a; Tatev Aslanyan 一、说明 我们将使用 PyTorch 从头开始构建生成式 AI、大型语言模型——包括嵌入、位置编码、多头自注意、残差连接、层归一化&#xff0c;Baby GPT 是一个探索性项目&#xff0c;旨在逐步构建类似 GPT 的语言模型。在这个项目中&#xff…

【教程】MySQL数据库学习笔记(五)——约束(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…

R: 阿尔法α多样性计算和箱图制作,以及差异分析

# install.packages("vegan") library(vegan) library(ggplot2) library(ggpubr)setwd("xxx") # 使用read.table()函数读取数据 df <- read.table("xxx", header TRUE, row.names 1)# 转置数据框 df <- t(df)# 计算每个样品的香农多样性…

【论文笔记】基于预训练模型的持续学习(Continual Learning)(增量学习,Incremental Learning)

论文链接&#xff1a;Continual Learning with Pre-Trained Models: A Survey 代码链接&#xff1a;Github: LAMDA-PILOT 持续学习&#xff08;Continual Learning, CL&#xff09;旨在使模型在学习新知识的同时能够保留原来的知识信息了&#xff0c;然而现实任务中&#xff…

《Linux运维总结:Kylin V10+ARM架构CPU基于docker-compose一键离线部署mongodb4.0.11之副本集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&…

前后端交互概念

前后端交互概念 1前后端分离开发概念2搭建后端环境2.1配置文件commomcommon-utilservice-utilmodelservice gitee使用 1前后端分离开发概念 前段&#xff1a;运用html、css、js和现成库&#xff0c;对数据作展示。 后端&#xff1a;运用Java和Java框架&#xff0c;提供数据或操…

【树莓派】如何刷个系统给树莓派4B,如何ssh登陆到树莓派

文章目录 下载树莓派镜像下载烧写软件烧写编辑设置连接树莓派4B重启ssh查看树莓派IPssh远程连接问询、帮助 下载树莓派镜像 https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit 下载烧写软件 https://www.raspberrypi.com/software/ 烧写 编辑…

fastadmin表单提交后却没有关闭弹窗

原文&#xff1a;https://www.cnblogs.com/youantianqin/p/11058142.html 特别提示&#xff1a;原文此方法不能完全解决我的问题。 我的问题&#xff1a;照着下文操作依然还是这样的情况 我的解决方法&#xff1a;见文末 问题回显&#xff1a; 点击操作按钮弹出窗口,操作完…

深入理解与实践“git add”命令的作用

文章目录 **git add命令的作用****git add命令的基本作用****高级用法与注意事项** git add命令的作用 引言&#xff1a; 在Git分布式版本控制系统中&#xff0c;git add命令扮演着至关重要的角色&#xff0c;它是将本地工作区的文件变动整合进版本控制流程的关键步骤。本文旨…

如何在Windows 10锁定时启用内置管理员?这里提供详细步骤

序言 当被锁定在Windows 10计算机之外时,如何启用内置管理员?正如我们所知,一旦启用了内置管理员,我们所有人都可以将其用作另一个本地管理员帐户来登录锁定的计算机。 当然,即使当你被锁定在Windows 10计算机之外时,你也可以启用内置管理员。你需要的只是Windows 10系…

【Linux】系统安全及应用

目录 一、账号安全基本措施 1.系统账号清理 2.密码安全控制 3.历史命令安全管理 4.限制su切换用户 1&#xff09;将信任的用户加入到wheel组中 2&#xff09;修改su的PAM认证配置文件 5.ssh远程登录输入三次密码错误则锁定用户 二、Linux中的PAM安全认证 1.su命令的…

open Gauss 数据库-06 openGauss数据库安全指导手册5.0.0

发文章是为了证明自己真的掌握了一个知识&#xff0c;同时给他人带来帮助&#xff0c;如有问题&#xff0c;欢迎指正&#xff0c;祝大家万事胜意&#xff01; 目录 前言 openGauss数据库安全指导 1 用户权限控制 1.1 实验介绍 1.1.1 关于本实验 1.1.2 实验目的 1.2 用户…