当前位置: 首页 > news >正文

顺序表专题

文章目录

  • 目录
    • 1. 数据结构相关概念
      • 1.1 什么是数据结构
      • 1.2 为什么需要数据结构
    • 2. 顺序表的概念及结构
    • 3. 顺序表分类
    • 4. 实现动态顺序表
      • 4.1 初始化
      • 4.2 顺序表的尾部插入
      • 4.3 打印顺序表
      • 4.4 顺序表的头部插入
      • 4.5 顺序表的尾部删除
      • 4.6 顺序表的头部删除
      • 4.7 指定位置之前插入数据
      • 4.8 删除指定位置数据
      • 4.9 在顺序表中查找x
      • 4.10 顺序表的销毁

目录

  • 数据结构相关概念
  • 顺序表概念及结构
  • 顺序表分类
  • 实现动态顺序表

1. 数据结构相关概念

1.1 什么是数据结构

数据结构是由“数据”和“结构”两词组合而来。

什么是数据?

常见的数值1、2、3、4…、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据。

什么是结构?

当我们想要大量使用同⼀类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将⼤量的数据组织在⼀起,结构也可以理解为组织数据的方式。

概念: 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在⼀种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由哪部分构成,以什么方式构成,以及数据元素之间呈现的结构。

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

1.2 为什么需要数据结构

程序中如果不对数据进行管理,可能会导致数据丢失、操作数据困难、野指针等情况。通过数据结构,能够有效将数据组织和管理在⼀起。按照我们的方式任意对数据进行增删改查等操作。

最基础的数据结构:数组。

【思考】有了数组,为什么还要学习其他的数据结构?

假定数组有10个空间,已经使用了5个,向数组中插入数据的步骤:

  1. 求数组的长度,求数组的有效数据个数
  2. 向下标为数据有效个数的位置插入数据(注意:这里是否要判断数组是否满了,满了还能继续插入吗)
  3. 假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。

结论: 最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。

2. 顺序表的概念及结构

线性表:

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的⼀条直线;但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

顺序表:

逻辑结构是线性的、物理结构是连续的。

顺序表和数组的区别:

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

3. 顺序表分类

  1. 静态顺序表

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

//静态顺序表#define N 100typedef int SLDataType;//顺序表中数组类型不一定是整型,如果要变为字符类型,就可以在这里直接改;如果不这样定义,就要在代码中改很多次struct SeqList
{SLDataType a[N];//定长数组int size;//有效数据个数
};

静态顺序表缺陷:空间给少了不够⽤,给多了造成空间浪费

  1. 动态顺序表
//动态顺序表typedef int SLDataType;typedef struct SeqList
{SLDataType* arr;//存储数据的底层结构int capacity;//记录顺序表的空间大小int size;//记录顺序表当前有效的数据个数
}SL;//typedef struct SeqList SL;

4. 实现动态顺序表

4.1 初始化

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

4.2 顺序表的尾部插入

void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = 0 == ps->capacity ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (NULL == tmp){perror("realloc fail!");exit(1);}//扩容成功ps->arr = tmp;ps->capacity = newCapacity;}
}void SLPushBack(SL* ps, SLDataType x)
{//断言 -- 粗暴的解决方式//assert(ps != NULL);assert(ps);//if判断 -- 温柔的解决方式//if (NULL == ps)//{//	return;//}//空间不够,扩容SLCheckCapacity(ps);//空间足够,直接插入ps->arr[ps->size++] = x;//ps->size++;
}

注:
扩容的原则:成倍数的增加(1.5倍、2倍)

4.3 打印顺序表

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

4.4 顺序表的头部插入

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);//判断是否扩容SLCheckCapacity(ps);//旧数据往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}

4.5 顺序表的尾部删除

void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//顺序表不为空ps->size--;
}

4.6 顺序表的头部删除

void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//不为空执行挪动操作for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

4.7 指定位置之前插入数据

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);//pos及之后的数据往后挪动一位,pos空出来for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}

4.8 删除指定位置数据

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//pos以后的数据往前挪动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

4.9 在顺序表中查找x

int SLFind(SL* ps, SLDataType x)
{//加上断言对代码的健壮性更好assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->arr[i]){return i;}}return -1;
}

4.10 顺序表的销毁

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

完整代码:

//SeqList.h#include <stdio.h>
#include <stdlib.h>
#include <assert.h>静态顺序表
//
//#define N 100
//
//typedef int SLDataType;
//
//struct SeqList
//{
//	SLDataType a[N];
//	int size;
//};//动态顺序表typedef int SLDataType;typedef struct SeqList
{SLDataType* arr;//存储数据的底层结构int capacity;//记录顺序表的空间大小int size;//记录顺序表当前有效的数据个数
}SL;//typedef struct SeqList SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);//保持接口一致性//顺序表的头部/尾部插入
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);//顺序表的头部/尾部删除
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);//指定位置之前插入数据
//删除指定位置数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);int SLFind(SL* ps, SLDataType x);
//SeqList.c#include "SeqList.h"//初始化和销毁
void SLInit(SL* ps)
{assert(ps);ps->arr = NULL;ps->size = ps->capacity = 0;
}void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = 0 == ps->capacity ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));if (NULL == tmp){perror("realloc fail!");exit(1);}//扩容成功ps->arr = tmp;ps->capacity = newCapacity;}
}//顺序表的头部/尾部插入
void SLPushBack(SL* ps, SLDataType x)
{//断言 -- 粗暴的解决方式//assert(ps != NULL);assert(ps);//if判断 -- 温柔的解决方式//if (NULL == ps)//{//	return;//}//空间不够,扩容SLCheckCapacity(ps);//空间足够,直接插入ps->arr[ps->size++] = x;//ps->size++;
}void SLPushFront(SL* ps, SLDataType x)
{assert(ps);//判断是否扩容SLCheckCapacity(ps);//旧数据往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}//顺序表的头部/尾部删除
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 - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);//pos及之后的数据往后挪动一位,pos空出来for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}//删除指定位置数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//pos以后的数据往前挪动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}//在顺序表中查找x
int SLFind(SL* ps, SLDataType x)
{//加上断言对代码的健壮性更好assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->arr[i]){return i;}}return -1;
}void SLDestroy(SL* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->size = ps->capacity = 0;
}void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
//test.c#include "SeqList.h"void slTest01()
{SL sl;SLInit(&sl);//测试尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPrint(&sl);//SLPushBack(&sl, 5);//SLPrint(&sl);//SLPushBack(NULL, 6);//头插//SLPushFront(&sl, 5);//SLPushFront(&sl, 6);//SLPushFront(&sl, 7);//SLPrint(&sl);//尾删//SLPopBack(&sl);//SLPopBack(&sl);//SLPopBack(&sl);//SLPopBack(&sl);//SLPrint(&sl);//头删//SLPopFront(&sl);//SLPopFront(&sl);//SLPopFront(&sl);//SLPopFront(&sl);//SLPrint(&sl);//指定位置插入//SLInsert(&sl, 0, 100);//SLPrint(&sl);//SLInsert(&sl, sl.size, 200);//SLPrint(&sl);//SLInsert(&sl, 100, 300);//SLPrint(&sl);//删除指定位置的数据//SLErase(&sl, 0);//SLPrint(&sl);//SLErase(&sl, sl.size - 1);//SLPrint(&sl);SLErase(&sl, 1);SLPrint(&sl);
}void slTest02()
{SL sl;SLInit(&sl);//测试尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPrint(&sl);//测试查找//int ret = SLFind(&sl, 3);int ret = SLFind(&sl, 30);if (ret < 0){printf("数据不存在,查找失败!");}else{printf("数据找到了,在下标为%d位置\n", ret);}
}int main()
{//slTest01();slTest02();return 0;
}

相关文章:

顺序表专题

文章目录 目录1. 数据结构相关概念1.1 什么是数据结构1.2 为什么需要数据结构 2. 顺序表的概念及结构3. 顺序表分类4. 实现动态顺序表4.1 初始化4.2 顺序表的尾部插入4.3 打印顺序表4.4 顺序表的头部插入4.5 顺序表的尾部删除4.6 顺序表的头部删除4.7 指定位置之前插入数据4.8 …...

手写SpringBoot(三)之自动配置

系列文章目录 手写SpringBoot&#xff08;一&#xff09;之简易版SpringBoot 手写SpringBoot&#xff08;二&#xff09;之动态切换Servlet容器 手写SpringBoot&#xff08;三&#xff09;之自动配置 手写SpringBoot&#xff08;四&#xff09;之bean动态加载 手写SpringBoot…...

vitepress builld报错

问题&#xff1a;build时报错&#xff1a;document/window is not defined。 背景&#xff1a;使用vitepress展示自定义的组件&#xff0c;之前build是没有问题了&#xff0c;由于新增了qr-code以及quill富文本组件&#xff0c;导致打包时报错。 原因&#xff1a;vitepress官…...

redis分布式锁-----基于Redis的SETNX命令的简单分布式锁实现

Redis的SETNX命令的简单分布式锁实现的Java示例 首先&#xff0c;确保你已经引入了Jedis这个Java Redis客户端库。你可以通过Maven或Gradle来添加依赖。 1、Maven依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifact…...

HTTP请求头中的Host表示是什么?

表示处理请求的服务器地址&#xff0c;由于一台服务器可能部署多个网站&#xff0c;如果通过域名访问&#xff0c;host就是域名...

apk被play protect blocked的解决方案(ADB+Appium+webdriverio)

起因:公司有海外项目&#xff0c;需要推广apk &#xff0c;数量多&#xff0c;但是由于被play protect阻止安装&#xff0c;初版解决方案 apk加固、换签名、垃圾代码、修改资源文件的MD5&#xff0c;但是由于原生代码标记过于严重&#xff0c;推广成本高&#xff0c;又换了一种…...

【BlossomRPC】手把手教你写一个RPC协议

文章目录 新的开始什么是RPC?设计一个RPC需要些什么&#xff1f; 新的开始 经常会遇到一些项目&#xff0c;看着看着就发现看不懂文档了&#xff0c;也就是会出现一些跳过讲解的文章&#xff0c;使得自己很难了解某种中间件的开发全貌&#xff0c;所以想着自己先设计一个比较…...

算法之美:堆排序原理剖析及应用案例分解实现

这段时间持续更新关于“二叉树”的专栏文章&#xff0c;关心的小伙伴们对于二叉树的基本原理已经有了初步的了解。接下来&#xff0c;我将会更深入地探究二叉树的原理&#xff0c;并且展示如何将这些原理应用到更广泛的场景中去。文章将延续前面文章的风格&#xff0c;尽量精炼…...

Net8 ABP VNext完美集成FreeSql、SqlSugar,实现聚合根增删改查,完全去掉EFCore

没有基础的&#xff0c;请参考上一篇 彩蛋到最后一张图里找 参考链接 结果直接上图&#xff0c;没有任何业务代码 启动后&#xff0c;已经有了基本的CRUD功能&#xff0c;还扩展了批量删除&#xff0c;与动态查询 动态查询截图&#xff0c;支持分页&#xff0c;排序 实现原理…...

yolov8直接调用zed相机实现三维测距(python)

yolov8直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 版本一2.1 相关代码2.2 实验结果 3. 版本二3.1 相关代码3.2 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1.yolov5直接调…...

element跑马灯/轮播图,第一页隐藏左边按钮,最后一页隐藏右边按钮(vue 开箱即用)

图示&#xff1a; 第一步&#xff1a; <el-carousel :class"changeIndex0?leftBtnNone:changeIndeximgDataList.length-1? rightBtnNone:" height"546px" :autoplay"false" change"changeNext"><el-carousel-item v-for…...

下载及安装PHP,composer,phpstudy,thinkPHP6.0框架

文章目录 目录 文章目录 前言 一、下载PHP 二、下载composer 三、下载PHPstudy 四、下载think PHP 1.下载 2.多应用开发 前言 thinkPHP是一款开源的PHP框架&#xff0c;它是基于MVC&#xff08;Model-View-Controller&#xff09;设计模式构建的。thinkPHP提供了丰富的…...

volatile使用场景总结

volatile关键字在Java中用于确保变量的可见性以及防止指令重排序&#xff0c;特别是在没有使用锁定机制时对变量进行读写的多线程环境中。以下是需要使用volatile修饰的一些场景&#xff1a; 确保变量的可见性 当一个变量被多个线程访问&#xff0c;且至少有一个线程在写&…...

AcWing 1413. 矩形牛棚(每日一题)

原题链接&#xff1a;1413. 矩形牛棚 - AcWing题库 作为一个资本家&#xff0c;农夫约翰希望通过购买更多的奶牛来扩大他的牛奶业务。 因此&#xff0c;他需要找地方建立一个新的牛棚。 约翰购买了一大块土地&#xff0c;这个土地可以看作是一个 R 行&#xff08;编号 1∼R&…...

macOS Sonoma 14.4.1 (23E224) 正式版发布,ISO、IPSW、PKG 下载

macOS Sonoma 14.4.1 (23E224) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 2024 年 3 月 26 日凌晨&#xff0c;macOS Sonoma 14.4.1 更新修复了一个可能导致连接到外部显示器的 USB 集线器无法被识别的问题。它还解决了可能导致 Java 应用程序意外退出的问题&#xff0c;并修…...

WPF使用外部字体,思源黑体,为例子

1.在工程中新建文件夹&#xff0c;命名为“Font"。 2.将下载好的字体文件复制到Font文件夹。 3.在工程中&#xff0c;加入静态资源 <Window.Resources><FontFamily x:Key"SYBold">/AnalyzeImage;Component/Font/#思源黑体 CN Bold</FontFamily…...

9、jenkins微服务持续集成(一)

文章目录 一、流程说明二、源码概述三、本地部署3.1 SpringCloud微服务部署本地运行微服务本地部署微服务3.2 静态Web前端部署四、Docker快速入门一、流程说明 Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 开发人员每天把代码提交到Gitlab代码仓库Jenkins从G…...

VOC(客户之声)赋能智能家居:打造个性化、交互式的未来生活体验

随着科技的飞速发展&#xff0c;智能家居已成为现代家庭不可或缺的一部分。然而&#xff0c;如何让智能家居更好地满足用户需求&#xff0c;提供更贴心、更智能的服务&#xff0c;一直是行业关注的焦点。在这个背景下&#xff0c;VOC&#xff08;客户之声&#xff09;作为一种用…...

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测 目录 时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测&#xff08;完整源码和数据…...

node.js学习(2)

版权声明 以下文章为尚硅谷PDF资料&#xff0c;B站视频链接&#xff1a;【尚硅谷Node.js零基础视频教程&#xff0c;nodejs新手到高手】仅供个人学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...