初阶数据结构【2】--顺序表(详细且通俗易懂,不看一下吗?)

news2024/10/19 7:31:19

本章概述

  • 线性表
  • 顺序表
  • 顺序表问题与思考
  • 彩蛋时刻!!!

线性表

  • 概念一些在逻辑上成线性关系的数据结构的集合线性表在逻辑上一定成线性结构,在物理层面上不一定成线性结构。常见的线性表:顺序表,链表,栈,队列,字符串……。
  • 逻辑线性结构就是人为想像的具有某种联系的结构,这种关系是线性的。如图所示:在这里插入图片描述
  • 线性物理结构在空间上是连续的,是线性的,就像火车一样,各个车厢是一节一节的连接的。反之,就是非线性物理结构。在内存中的体现就是地址空间是连续的,如图所示:在这里插入图片描述
  • 为什么有的线性表物理上不是线性结构呢?:这就好比我们在一家餐馆排队取餐一样,我们都各自排好队,人与人之间可能并不是紧挨着排队,我们之间会前后错落,这就导致我们在物理空间上不是连续的,不是线性的。但是,我们在逻辑上是线性的,因为我们都是前后交错的,不能乱插队。如图所示:在这里插入图片描述
    线性表是这些在逻辑上成线性结构的数据结构的统称,就像苹果,西瓜,香蕉……这些都统称为水果,线性表也是这个意思。其它线性数据结构,我会不断的给大家分享的,继续往后学习,你就会体会到这种线性存储数据的巧妙之处。

顺序表

  • 概念在逻辑和物理上都成线性关系的数据结构它是以数组为底层来进行数据存储的,所以在物理上体现线性。 如图所示:在这里插入图片描述
    读到这里,可能就有人有疑问了——既然顺序表是用数组来实现的,那么两者的区别是什么? 在讲这个问题之前,我先给大家看个图在这里插入图片描述
    我来解释一下这个图的意思:炒西兰花和绿野仙踪的本质都是西兰花,但是,对西兰花进行装饰和好看的摆盘,就成了绿野仙踪(价格也漂亮!),就是对西兰花进行了漂亮的封装一个普通的数组可以进行数据的存储和数据的访问,功能很少。但是,经过对数组进行封装,我们在它原来的功能基础上增加了删除数据,增加数据和自动增加数组容量,就摇身一变成了顺序表。
  • 结构顺序表的基本功能要对数据进行存储,所以我们自然少不了数组形式的存储。我们还要知道这个顺序表的有效数据个数(存储了多少个数据)对于动态顺序表,我们还要知道顺序表的容量。所以,针对于以上的特征我们要用到结构体。结构体知识忘的同学可以回顾:点击:《结构体》。
  • 分类分为静态顺序表动态顺序表
    • 静态顺序表:以定长数组为原理进行存储。 结构如图所示:在这里插入图片描述
      静态顺序表有个致命的缺点——容量大小是固定的。我们静态顺序表里面的数组大小是固定的,当我们要存储的数据量较多时,就会出现空间不够用,当我们存储的数据量很少时,就会出现空间的大量浪费。为了避免空间的不足或浪费,我们每次都要调整数组的容量,这就很不方便,代码执行效率太低了。所以,我们一般不用静态顺序表。我们最常用的是动态顺序表——因为它能自动改变数组的容量
    • 动态顺序表:用动态内存函数realloc进行空间的申请。结构如图所示:在这里插入图片描述
      动态顺序表相对于静态顺序表,里面多了一些东西。因为我们是在原来空间基础上扩容的,所以要用realloc,又因为我们要用动态内存函数realloc进行空间的开辟,所以我们要用SLDatatype * arr;来接受malloc因为存储什么类型的数据,我们不知道,所以要用typedef宏定义,我们根据数据类型直接改宏定义,就能改变全局数据类型。capacity就是用来确定我们要开辟的空间大小。我们后面展示的代码都是以动态数组为根据的。
  • 动态顺序表的实现:我们要建立三个文件来实现动态顺序表
1. 建个Sqlist.h文件:用于函数和结构体的声明。
2. 建个Sqlist.c文件:用于实现各个功能函数。
3. 建个 test.c 文件:用来测试顺序表的功能。

进行图片展示:在这里插入图片描述
接下来,我直接给大家展示顺序表的各个功能代码的实现。

  • Sqlist.h
#pragma once     	  	//头文件的定义格式
#include <stdio.h>   	//我们直接把需要的头文件都定义在<Sqlist.h>,
#include <stdlib.h>		//我们就不用在<test.c>写这些头文件了。
#include <assert.h>
typedef int SLDatatype;  //宏定义,便于我们后续修改数据类型。
typedef struct Sqlist
{
	SLDatatype* arr;   //接收malloc返回的空间地址
	int size;      //有效数据个数
	int capacity; 	 //顺序表的容量
}SL;

void SqlistNit(SL* pp); //顺序表初始化
void my_printf(SL* p);  //打印函数
void Sqlistcheck(SL* p);  //检查空间够不够

void Sqlistpopback(SL* p); //尾部删数据
void Sqlistpushback(SL* ps, SLDatatype x); //数据尾插

void SqlistpopFront(SL* ps); //数据头删
void SqlistpushFront(SL* ps, SLDatatype x); //数据头插

void SqlistpushSy(SL* p, int da, SLDatatype x);//任意位置插入数据
  • Sqlist.c
#define  _CRT_SECURE_NO_WARNINGS	1
#include "Sqlist.h"  //引用<Sqlist.h>头文件
void Sqlistcheck(SL*p)   //检查空间够不够
{
	assert(p);   //传递的指针不能为空
	if (p->size == p->capacity)
	{
		int newcapacity = p->capacity == 0 ? 4 : p->capacity * 2; //当容量不够时,就自动扩容原来的2倍。
		p->capacity = newcapacity;
		SLDatatype* temp = (SLDatatype*)realloc(p->arr, newcapacity * 2 * sizeof(SLDatatype));  //malloc开辟空间,用temp接收,要注意类型的转换。
		if (temp != NULL)
			p->arr = temp;  //判断空间开辟是否成功,开辟成功就赋值
		else
			return 1;  //开辟失败就直接返回
	}
}
void Sqlistpushback(SL*ps,SLDatatype x)  //数据尾插
{
	assert(ps); //判断传递的是否为空指针
	Sqlistcheck(ps); //检查空间够不够
	ps->arr[ps->size++] = x; 
}
void SqlistpushFront(SL*ps,SLDatatype x)  //数据头插
{
	assert(ps);  //判断传递的是否为空指针
	Sqlistcheck(ps); //检查空间够不够
	for (int i = ps->size;i>0; i--)
	{
		ps->arr[i] = ps->arr[i-1];
	}
	ps->arr[0] = x;
	ps->size++;  //因为我们插入了数据,所以有效数据个数就要增加。
}
void SqlistpopFront(SL*ps)  //数据头删
{
	assert(ps&&ps->size);  //有效数据个数不能为空,要不然就不用删了
	for (int i = 0; i + 1 < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i+1];
	}
	ps->size--;  //因为删除了数据,所以有效数据个数就减少
}
void SqlistNit(SL*pp)    //初始化
{
	pp->arr = NULL; //防止野指针的发生
	pp->size = pp->capacity = 0;
}
void my_printf(SL* p)  //打印数据
{
	int i = 0;
	for (i = 0; i < p->size; i++)
	{
		printf("%d ",p->arr[i]);
	}
	printf("\n");
}
void Sqlistpopback(SL* p)  //尾部删数据
{
	assert(p);   	//判断传递的是否为空指针
	--p->size; 		 //因为删除了数据,所以有效数据个数就减少
}
void SqlistpushSy(SL* p,int da,SLDatatype x) //任意位置插入数据
{
	assert(p);  //判断传递的是否为空指针
	Sqlistcheck(p);  //检查空间是否足够
	for (int i = p->size;i-1>=da; i--)
	{
		p->arr[i] = p->arr[i-1];
	}
	p->arr[da] = x;
	p ->size++;   //插入数据,有效数据个数就增加
}

我们对于容量的扩容,一般采用2倍扩容。前提是整数倍,因为内存空间没有小数这一说,当小于2倍时,扩容量较小,数据可能存放不下,当大于2倍时,扩容量较大,空间浪费。所以,我们一般采用2倍扩容,刚好在起始位置上增加1倍空间。

  • test.c :用来测试顺序表的各个功能函数。
#define  _CRT_SECURE_NO_WARNINGS	1
#include "Sqlist.h"
// 可以根据自己的需求来自行测试顺序表的各个函数的功能
void test()
{
	SL s1;
	SqlistNit(&s1);   		//给大家举个顺序表插入数据的例子
	Sqlistpushback(&s1,2);
	Sqlistpushback(&s1,2);
	Sqlistpushback(&s1,2);
	Sqlistpushback(&s1,2);
	my_printf(&s1);
}
int main()
{
	test();
	return 0;
}

结果运行图:在这里插入图片描述

  • 总结因为动态顺序表的空间和数组一样,所以我们就可以可以通过++- -来对空间进行访问。我们要注意传递的指针是否为空指针,当删除或插入数据时,要注意有效数据个数的变化。
  • 对于动态内存开辟不懂得同学可以查看:点击:《动态内存管理》。
  • 对于指针(一级和二级指针)不懂得同学可以查看:点击:《深入理解指针1》.

顺序表问题与思考

  • 中间/头部的插入删除,时间复杂度为O(n).
  • 增容需要申请新空间,拷贝数据,释放就空间,会有不小的消耗,执行效率不是很好。
  • 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再插入5个数据后,那么就会有95个空间浪费了。思考一下:我们该怎样解决以上的问题呢?预告:下期《链表》就会解决的

彩蛋时刻!!!

给大家听个欢快的曲子,给大家放松放松一下:机器人之梦:《September》在这里插入图片描述
每章一句人生漫长,祝我们都可爱的不像话!感谢你能看到这里,点赞+关注+收藏+转发是对我最大的鼓励,咱们下期见!!!

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

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

相关文章

Origin画图——百分比堆积柱状图(深度学习篇)

1.当数据有以下特征&#xff0c;不同特征在不同情况下的数值的时候就可以使用百分比柱状图表示。 1 2.将自己的数据导入到Origin中&#xff0c;本示例中以不同机器学习的方法的在不同测试集下的R2作为示例。数据如下所示。绘图百分比柱状图&#xff0c;两种都可以。 3.生成的…

推荐一个可以免费上传PDF产品图册的网站

​在数字化时代&#xff0c;企业将产品图册以PDF格式上传至网络&#xff0c;不仅便于客户浏览和下载&#xff0c;还能提升企业的专业形象。今天&#xff0c;就为您推荐一个可以免费上传PDF产品图册的网站——FLBOOK&#xff0c;轻松实现产品图册的在线展示。 1.注册登录&#x…

【xilinx-versal】【Petalinux】添加TMP75温度传感器Linux驱动

Xilinx versal添加TMP75温度传感器Linux驱动 I2C总线的内核配置打开Cadence I2C 控制器配置xilinx I2C配置(不使用)添加设备树总结I2C总线的内核配置 TMP75挂载第一个i2c总线上,地址是0x48。 petalinux-config -c kernel打开内核配置界面。 打开Cadence I2C 控制器配置 │…

Linux——用户/用户组

创建用户组groupadd groupadd 用户组 删除用户组groupdel groupdel 用户组 创建用户useradd useradd 用户名 - g 用户组 useradd 用户名 -d HOME路径 删除用户userdel userdel 用户 userdel -r 用户 &#xff08;删除用户的 HOME 目录&#xff0c;不使用 -r &#xff0…

FlinkCDC 实现 MySQL 数据变更实时同步

文章目录 1、基本介绍2、代码实战2.1、数据源准备2.2、代码实战2.3、数据格式 1、基本介绍 Flink CDC 是 Apache Flink 提供的一个功能强大的组件&#xff0c;用于实时捕获和处理数据库中的数据变更。可以实时地从各种数据库&#xff08;如MySQL、PostgreSQL、Oracle、MongoDB…

结构体通讲——数据结构解惑

文章目录 一.第一种写法二.第二种三.第三种四.-> 结构&#xff1a;一个变量里包含很多变量 一.第一种写法 int a[]&#xff1b;//一个数组中可以包含许多相同类型的数组 想让一个数组中包含很多不同类型的变量用结构 struct {int a;char bc; }t,ti;//t和ti拥有了前面所定…

谷歌审核放宽,恶意软件不再封号?是反垄断案影响还是开发者们的错觉

最近&#xff0c;谷歌因其“垄断”案而成为科技行业的焦点&#xff0c;这个案件可能导致谷歌业务的重大调整。同时&#xff0c;在Google Play上&#xff0c;一些开发者发现谷歌审核好像放宽了不少&#xff0c;这是不是与反垄断有关&#xff0c;谷歌应用上架或将迎来春天&#x…

MySQL-12.DQL-条件查询

一.DQL-条件查询 -- DQL:条件查询 -- 1.查询 姓名 为 杨逍 的员工 select id, username, password, name, gender, image, job, entrydate, create_time, update_timefrom tb_emp where name 杨逍;-- 2.查询 id小于等于5 的员工信息 select * from tb_emp where id < 5;-…

HT3382 2x75W D类立体声音频功放

1、特点 输出功率(BTL) 2x60W (VDD24V,RL4Ω,THDN1%) 2x75W(VDD24V,RL4Ω,THDN10%) 输出功率(PBTL) 115W(VDD24V,RL2Ω,THDN1%) 140W(VDD24V,RL2Ω,THDN10%) 单电源系统&#xff0c;4.5V-26V宽电压输入范围 超过93%效率&#xff0c;需散热器 扩频功能 MUTE功能 模拟差分/单端输…

LLM - 使用 Neo4j 可视化 GraphRAG 构建的 知识图谱(KG) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142938982 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Neo4j …

中科大科大讯飞开源OpenMusic:音乐生成更高质量,更有乐感

文章链接&#xff1a;https://arxiv.org/pdf/2405.15863 代码链接&#xff1a;https://github.com/ivcylc/qa-mdt Huggingface链接&#xff1a;https://huggingface.co/spaces/jadechoghari/OpenMusic Demo链接&#xff1a;https://qa-mdt.github.io/ &#xff08;chatgpt * 3…

苹果 AI 及国产大模型之争:悬念不再?

AI基本盘&#xff0c;牢牢把握在苹果手里 苹果终于公布了最新的AI进程。 一个月前&#xff0c;正如此前预期的那样&#xff0c;人工智能是今年 WWDC 发布会的焦点。全程105分钟的主题演讲&#xff0c;就有40多分钟用于介绍苹果的AI成果。 苹果似乎还有意玩了一把“谐音梗”&…

人脸识别-特征算法

文章目录 一、LBPH算法1.基本原理2.实现步骤3.代码实现 二、Eigenfaces算法1.特点2.代码实习 三、FisherFaces算法1.算法原理2.算法特点3.代码实现 四、总结 人脸识别特征识别器是数字信息发展中的一种生物特征识别技术&#xff0c;其核心在于通过特定的算法和技术手段&#xf…

跟李沐学AI—pytorch版本锚框代码解析

网上大佬的解释 https://fkjkkll.github.io/2021/11/23/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8BSSD/?highlight%E9%94%9A%E6%A1%86 w torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),sizes[0] * torch.sqrt(ratio_tensor[1:])))\* in_height / in_widthh torch.cat((…

当贝投影双十一战报揭晓:天猫投影品类销量稳居首位

相比往年&#xff0c;2024年双11提前了10天&#xff0c;于10月14日正式拉开帷幕。其中&#xff0c;作为国内智能投影头部品牌之一的当贝投影&#xff0c;首战告捷&#xff0c;迎来开门红&#xff0c;战绩相当喜人&#xff01; 根据当贝投影官方数据显示&#xff0c;10月至今当贝…

基于SpringBoot的在线视频教育平台的设计与实现(论文+源码)_kaic

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线视频教育平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线视频教育平台&#xff0c;它彻底改变了过…

vue 2.0 使用 html2canvas + jspdf +ant-design-vue 1.x + echarts + 高德地图 导出数据报告

思路&#xff1a; 1. 因为html转为图片再加入到PDF中 会导致截断&#xff0c;因此前端自定义分页添加 类 &#xff08;page&#xff09; 2. 通过page生成图片 在加入PDF中<template><div id"pdf-content"><div class"page first-page">&…

Jmeter接口测试企业级项目实战day2

1.JMeter接口关联 含义&#xff1a;把上一个接口的响应内容&#xff0c;作为下一个接口的请求参数 思路&#xff1a;通过变量来传递数据 步骤&#xff1a; 1.创建&#xff1a;上一个接口&#xff0c;添加【后置处理器】&#xff1a;提取数据创建变量 2.使用&am…

项目分析:自然语言处理(语言情感分析)

在这个信息爆炸的时代&#xff0c;我们每天都在与海量的文本数据打交道。从社交媒体上的帖子、在线评论到新闻报道&#xff0c;文本信息无处不在。然而&#xff0c;这些文本不仅仅是文字的堆砌&#xff0c;它们背后蕴含着丰富的情感和观点。如何有效地理解和分析这些情感&#…

leetcode48:旋转矩阵

题目&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5…