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

[数据结构]动态顺序表的实现与应用

文章目录

  • 一、引言
  • 二、动态顺序表的基本概念
  • 三、动态顺序表的实现
    • 1、结构体定义
    • 2、初始化
    • 3、销毁
    • 4、扩容
    • 5、缩容
    • 5、打印
    • 6、增删查改
  • 四、分析动态顺序表
    • 1、存储方式
    • 2、优点
    • 3、缺点
  • 五、总结
    • 1、练习题
    • 2、源代码

一、引言

想象一下,你有一个箱子(静态顺序表),它的大小是固定的,你只能在这个箱子里面放东西或者拿出来,如果东西放不下了,箱子就满了,没办法再放更多。但现在,我们有了一种更灵活的箱子 —— 动态顺序表。这个箱子不仅能放东西,还能根据需要自动变大或变小,非常方便。

不过,要想玩转这个神奇的箱子,我们得先对里面的 “东西” (数据)的存放方式有所了解,也就是得熟悉数组和指针。如果你对这些还不太熟悉,别担心,我已经为你准备了一篇文章作为参考:传送门。读完之后,你会发现它们其实并不复杂。


二、动态顺序表的基本概念

动态顺序表,简单来说,就是一个可以 “长大” 或 “缩小” 的箱子。它不像静态顺序表那样一开始就确定了大小,而是根据我们需要存放的东西的多少来动态地调整自己的大小。

当我们往动态顺序表里放东西时,如果箱子满了,它就会自动去找一个更大的箱子,然后把原来的东西和新东西一起放进去。这个过程就像是我们换了一个更大的家,然后把所有家具都搬进去一样。

反过来,如果我们从动态顺序表里拿走了很多东西,箱子变得空荡荡的,那它也会考虑换个小点的箱子住,毕竟节省空间也是一种美德嘛。

总之,动态顺序表就是这样一个既智能又灵活的箱子,它能够帮助我们更加高效地管理和存储数据。

请添加图片描述


三、动态顺序表的实现

1、结构体定义

首先,我们需要定义一个结构体来表示动态顺序表,这个结构体将包含指向数组元素的指针、当前存储的元素数量以及分配的空间大小。

typedef int DataType;
typedef struct {DataType* arr;//指向动态数组的指针int size;//当前存储的元素个数int capacity;//当前动态数组的容量
}Seq;

2、初始化

初始化动态顺序表时,我们需要为其分配一个初始的空间大小,并设置当前存储的元素数量为0。

void Init(Seq* ps, int capacity)
{capacity == 0 ? capacity = 2 : capacity;DataType* pos = (DataType*)malloc(sizeof(DataType) * capacity);if (pos == NULL){fprintf(stderr, "内存分配失败\n");exit(EXIT_FAILURE);}ps->array = pos;ps->capacity = capacity;ps->size = 0;
}

3、销毁

使用完动态顺序表后,需要释放分配的内存,避免内存泄漏。

void Destroy(Seq* ps)
{if (ps == NULL)return;free(ps->array);ps->array = NULL;ps->capacity = 0;ps->size = 0;
}

4、扩容

当向动态顺序表中添加元素时,如果当前空间已满,则需要进行扩容操作。扩容通常会将容量加倍。

void Reserve(Seq* ps)
{if (ps->size == ps->capacity){int capacity = ps->capacity == 0 ? 2 : ps->capacity * 2;DataType* pos = (DataType*)realloc(ps->array, capacity * sizeof(DataType));if (pos == NULL){fprintf(stderr, "内存分配失败\n");exit(EXIT_FAILURE);}ps->array = pos;ps->capacity = capacity;}
}

5、缩容

当删除动态顺序表中的元素时,如果当前空间过大,则需要进行缩容操作。

void Shrink(Seq* ps)
{if (ps->capacity >= 64 && ps->size < ps->capacity / 2.5){int capacity = ps->capacity / 2;DataType* pos = (DataType*)realloc(ps->array, capacity * sizeof(DataType));if (pos == NULL){fprintf(stderr, "内存分配失败");exit(EXIT_FAILURE);}ps->array = pos;ps->capacity = capacity;}
}

5、打印

为了方便调试和查看动态顺序表中的内容,我们可以实现一个打印函数,将所有元素打印出来。

void Print(Seq* ps, void (*Pr) (DataType))
{for (int i = 0; i < ps->size; i++){Pr(ps->array[i]);}printf("NULL\n");
}

6、增删查改

实现顺序表的基本操作,让顺序表更具有实用性。

void PushFront(Seq* ps, DataType data)
{Insert(ps, 0, data);
}void PopFront(Seq* ps)
{Erase(ps, 0);
}void PushBack(Seq* ps, DataType data)
{Insert(ps, ps->size, data);
}void PopBack(Seq* ps)
{Erase(ps, ps->size - 1);
}void Insert(Seq* ps, int x, DataType data)
{assert(x >= 0 && x <= ps->size);Reserve(ps);for (int i = ps->size - 1; i >= x; i--){ps->array[i + 1] = ps->array[i];}ps->array[x] = data;ps->size++;
}void Erase(Seq* ps, int x)
{assert(ps != NULL && ps->size > 0 && x >= 0 && x < ps->size);for (int i = x; i < ps->size - 1; i++){ps->array[i] = ps->array[i + 1];}ps->size--;
}int Find(Seq* ps, DataType data)
{for (int i = 0; i < ps->size; i++){if (ps->array[i] == data){return i;}}return -1;
}void Modify(Seq* ps, int x, DataType data)
{assert(ps != NULL && ps->size > 0 && x >= 0 && x < ps->size);ps->array[x] = data;
}

四、分析动态顺序表

1、存储方式

顺序表是线性表的一种,线性表的逻辑结构是连续的,物理结构是不一定连续的。顺序表使用数组进行存储,数组在内存中是连续的,所以顺序表的物理结构是连续的。

2、优点

顺序表在随机访问时具有很高的效率,因为数组在内存中是连续的,所以可以通过下标直接访问到对应的元素。

3、缺点

顺序表在插入和删除元素时,需要移动大量元素,所以效率较低。另外,顺序表的大小是固定的,如果需要扩容,需要重新分配内存,这也会带来一定的开销。


五、总结

1、练习题

  • 移除元素
  • 合并两个有序数组
  • 盛水最多的容器
  • 接雨水
  • 合并区间
  • 插入区间

2、源代码

对于动态顺序表的源代码我已经开源在GItee:传送门
建议读者,仔细阅读源代码,理解数据结构的设计思路,尝试修改和扩展功能以加深理解。通过编写测试案例来验证理解和代码的正确性。


相关文章:

[数据结构]动态顺序表的实现与应用

文章目录 一、引言二、动态顺序表的基本概念三、动态顺序表的实现1、结构体定义2、初始化3、销毁4、扩容5、缩容5、打印6、增删查改 四、分析动态顺序表1、存储方式2、优点3、缺点 五、总结1、练习题2、源代码 一、引言 想象一下&#xff0c;你有一个箱子&#xff08;静态顺序…...

Invalid Private Key, Not a valid string or uint8Array

报这种错误&#xff1a;一般在生成private key前面添加"0x"即可解决。我就是在私钥前面添加了"0x"解决了。 在学习web3时&#xff0c;使用助词生成的私钥&#xff0c;然后由私钥导出keystore就报错&#xff1a; ERROR Invalid Private Key, Not a valid …...

【Text2SQL】PET-SQL:在Spider基准测试中取得了SOTA

解读&#xff1a;PET-SQL: A Prompt-enhanced Two-stage Text-to-SQL Framework with Cross-consistency 这篇论文介绍了一个名为 PET-SQL 的文本到 SQL&#xff08;Text-to-SQL&#xff09;框架&#xff0c;旨在通过增强提示&#xff08;prompt&#xff09;和利用不同大型语言…...

python-3n+1数链/233

一&#xff1a;3n1数链题目描述 在计算机科学上&#xff0c;有很多类问题是无法解决的&#xff0c;我们称之为不可解决问题。然而&#xff0c;在很多情况下我们并不知道哪一类问题可以解决&#xff0c;哪一类问题不可解决。现在我们就有这样一个问题&#xff0c;问题如下&#…...

vue2基础系列教程之v-model及面试高频问题

v-model是表单组件里面的核心知识点&#xff0c;这个指令给我们写表单业务带来了很大的方便。 元素标签上的 v-model 指令用于双向绑定数据,它是一个语法糖&#xff0c;可以用于代替 v-bind:value 和 input 例如&#xff1a;<input v-model"message" placeholder…...

【高分系列卫星简介——高分一号(GF-1)】

高分一号卫星&#xff08;GF-1&#xff09; 高分一号&#xff08;GF-1&#xff09;是中国高分辨率对地观测系统&#xff08;简称“高分专项”&#xff09;的第一颗卫星&#xff0c;具有里程碑式的意义。以下是对高分一号卫星的详细介绍&#xff1a; 一、基本信息 发射时间&…...

Python基于TensorFlow实现时间序列循环神经网络回归模型(LSTM时间序列回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着信息技术的发展和传感器设备的广泛应用&#xff0c;时间序列数据的产生量急剧增加。无论是股市价格…...

springboot实战学习(6)(用户模块的登录认证)(初识令牌)(JWT)

接着上篇博客学习。上篇博客是在基本完成用户模块的注册接口的开发以及注册时的参数合法性校验的基础上&#xff0c;基本完成用户模块的登录接口的主逻辑。具体往回看了解的链接如下。 springboot实战学习笔记&#xff08;5&#xff09;(用户登录接口的主逻辑)-CSDN博客文章浏览…...

二叉树的顺序存储和基本操作实现

写代码&#xff1a;定义顺序存储的二叉树&#xff08;数组实现&#xff0c;树的结点从数组下标1开始存储&#xff09; 基于上述定义&#xff0c;写一个函数 int findFather ( i ) &#xff0c;返回结点 i 的父节点编号 基于上述定义&#xff0c;写一个函数 int leftChild ( i…...

python学习-10【模块】

1、认识模块 导入模块 使用 import 语句使用 from … import 语句 1、import modulename [as alias] modulename&#xff1a;表示要导入的模块名as alias&#xff1a;可选参数&#xff0c;为模块起的别名 2、from modulename import name modulename&#xff1a;模块名&#x…...

modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持

一、前言说明 搞物联网开发很多年&#xff0c;用的最多的当属modbus协议&#xff0c;一个稳定好用的物联网组件是物联网平台持续运行多年的基石&#xff0c;所以这个物联网组件从一开始就定位于自研&#xff0c;为了满足各种场景的需求&#xff0c;当然最重要的一点就是大大提…...

数值计算 --- 平方根倒数快速算法(0x5f3759df,这是什么鬼!!!)

平方根倒数快速算法 --- 向Greg Walsh致敬&#xff01; 1&#xff0c;牛顿拉夫逊 已知x&#xff0c;要计算&#xff0c;假设的值为a&#xff0c;则&#xff1a; &#xff0c;&#xff08;式1&#xff09; 如果定义一个自变量为a的函数f(a): 则&#xff0c;令函数f(a)等于0的a就…...

迭代器和生成器的学习笔记

迭代器 Python 迭代器是一种对象&#xff0c;它实现了迭代协议&#xff0c;包括 __iter__() 和 __next__() 方法。迭代器可以让你在数据集中逐个访问元素&#xff0c;而无需关心数据结构的底层实现。与列表或其他集合相比&#xff0c;迭代器可以节省内存&#xff0c;因…...

ES5 在 Web 上的现状

最后一个支持 ES5 的浏览器 IE 11 在 2022 年被微软停止支持&#xff0c;那么今天 Web 上的 ES5 现状如何&#xff1f;在构建生产代码时&#xff0c;Web 开发者的最佳实践是什么&#xff1f; 本文将通过数据来回答这些问题&#xff0c;并基于这些数据为网站开发者和库作者提供一…...

人话学Python-循环语句

一&#xff1a;while语句 while语句的组成由判断条件和执行语句组成。当满足条件时会不断执行后续语句&#xff0c;然后再循环执行的语句结束之后再次回到条件判断&#xff0c;如此循环。 pos 0 ans 0 while pos < 6:ans pos * 4pos 1 print(ans)>>>84"&…...

初识模版!!

初识模版 1.泛型编程1.1 如何实现一个交换函数呢&#xff08;使得所有数据都可以交换&#xff09;&#xff1f;1.2 那可以不可以让编译器根据不同的类型利用该模子来生成代码呢&#xff1f; 2.模版类型2.1 模版概念2.2 函数模版的原理2.3 函数模板的实例化2.4 模板参数的匹配原…...

算法之数学--hash算法 2021-03-11(未完待续)

1.hash算法 刷出一道墙 题目描述 Time Limit: 2000 ms Memory Limit: 256 mb 在一面很长的墙壁上&#xff0c;工人们用不同的油漆去刷墙&#xff0c;然而可能有些地方刷过以后觉得不好看&#xff0c;他们会重新刷一下。有些部分因为重复刷了很多次覆盖了很多层油漆&#xff…...

DHCP工作原理

在学习之前先提出几个问题&#xff1a;什么是DHCP&#xff1f;为什么要使用DHCP&#xff1f;在什么场景中使用DHCP&#xff1f;DHCP报文的目的IP和目的MAC是多少&#xff1f;DHCP报文是基于UDP还是基于TCP&#xff1f;DHCP服务器返回的报文中都包含什么信息&#xff1f; DHCP&a…...

服务发现和代理实例的自动更新

☞ 返回总目录 1.服务发现的两种方式 StartFindService 方法 这是一个在后台启动的连续 “FindService” 活动&#xff0c;当服务实例的可用性发生变化时&#xff0c;会通过回调通知调用者。 它返回一个FindServiceHandle&#xff0c;可通过调用StopFindService来停止正在进行…...

Redis的三种持久化方法详解

Redis持久化机制详解 | JavaGuide Redis 不同于 Memcached 的很重要一点就是&#xff0c;Redis 支持持久化&#xff0c;而且支持 3 种持久化方式: 快照&#xff08;snapshotting&#xff0c;RDB&#xff09;只追加文件&#xff08;append-only file, AOF&#xff09;RDB 和 A…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

HTML中各种标签的作用

一、HTML文件主要标签结构及说明 1. <&#xff01;DOCTYPE html> 作用&#xff1a;声明文档类型&#xff0c;告知浏览器这是 HTML5 文档。 必须&#xff1a;是。 2. <html lang“zh”>. </html> 作用&#xff1a;包裹整个网页内容&#xff0c;lang"z…...

Android Framework预装traceroute执行文件到system/bin下

文章目录 Android SDK中寻找traceroute代码内置traceroute到SDK中traceroute参数说明-I 参数&#xff08;使用 ICMP Echo 请求&#xff09;-T 参数&#xff08;使用 TCP SYN 包&#xff09; 相关文章 Android SDK中寻找traceroute代码 设备使用的是Android 11&#xff0c;在/s…...

视觉slam--框架

视觉里程计的框架 传感器 VO--front end VO的缺点 后端--back end 后端对什么数据进行优化 利用什么数据进行优化的 后端是怎么进行优化的 回环检测 建图 建图是指构建地图的过程。 构建的地图是点云地图还是什么信息的地图&#xff1f; 建图并没有一个固定的形式和算法…...

基于微信小程序的作业管理系统源码数据库文档

作业管理系统 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和微信小程序来完成对系统的…...

win11部署suna

参考链接 项目链接 沙盒链接 数据库链接 本文介绍 本文只为项目的辅助&#xff0c;手把手太麻烦 执行步骤 1.下载代码 git clone https://github.com/kortix-ai/suna.git cd suna2.配置环境&#xff08;在Anaconda Prompt上执行&#xff09; python setup.py3.运行代码 …...