栈,队列和链表三者之间的关系与区别

news2024/12/30 1:44:44

最近一直在学习算法,刷算法题,但是自从大学毕业以来,数据结构的知识都还给老师了,只会个数组,所以前期刷的题目也都是有关数组的

最近跟着小册重学了一遍数据结构,今天就记录一下栈,队列和链表三者之间的关系与区别,以及如何进行增删

栈和队列的实现一般都要依赖于数组,大家完全可以把栈和队列都看作是“特别的数组”。

两者的区别在于,它们各自对数组的增删操作有着不一样的限制。

要想学会栈和队列就必须要了解数组的几种增删方法

数组中增加元素的三种方法

  • unshift添加元素到数组的头部* push添加元素到数组的尾部* splice添加元素到数组的任何位置数组中删除元素的三种方法

  • shift删除数组头部的元素* pop删除数组尾部的元素* splice删除数组任意位置的元素栈(Stack)
    ========

栈是 只用poppush 完成增删的“数组”

栈是一种后进先出(LIFO,Last In First Out)的数据结构。

就拿小卖部老板放冰糕和卖冰糕举例:

他有两个特征:

  • 只允许从尾部添加元素* 只允许从尾部取出元素对应到数组的方法,刚好就是 push 和 pop。因此,我们可以认为在 JavaScript 中,栈就是限制只能用 push 来添加元素,同时只能用 pop 来移除元素的一种特殊的数组。

栈顶元素:所谓栈顶元素,从图上我们不难看出来,实际上它指的就是数组尾部的元素。

// 初始状态,栈空
const stack = []// 入栈过程
stack.push('东北大板')
stack.push('可爱多')
stack.push('巧乐兹')

// 栈顶元素 就是最后一个元素
stack[stack.length-1]

// 出栈过程,栈不为空时才执行
while(stack.length) {// 单纯访问栈顶元素(不出栈)const top = stack[stack.length-1]console.log('现在取出的冰淇淋是', top)// 将栈顶元素出栈stack.pop()
}

// 栈空
stack // [] 

队列(Queue)

队列是(Queue)只用 push 和 shift 完成增删的“数组”

队列是一种先进先出(FIFO,First In First Out)的数据结构。


就像派对做核酸

队列的特征就是:

  • 只允许从尾部添加元素
  • 只允许从头部移除元素

整个过程只涉及了数组的 pushshift 方法。

在栈元素出栈时,我们关心的是栈顶元素(数组的最后一个元素);队列元素出队时,我们关心的则是队头元素(数组的第一个元素)。

链表

链表和数组相似,它们都是有序的列表、都是线性结构(有且仅有一个前驱、有且仅有一个后继)。不同点在于,链表中,数据单位的名称叫做“结点”,而结点和结点的分布,在内存中可以是离散的。

数组的元素分布示意图:

而链表中的结点,则允许散落在内存空间的各个角落里。一个内容为1->2->3->4->5的链表,在内存中的形态可以是散乱如下的:

正是由于数组中的元素是连续的,每个元素的内存地址可以根据其索引距离数组头部的距离来计算出来。因此对数组来说,每一个元素都可以通过数组的索引下标直接定位。对链表来说,元素和元素之间似乎毫无内存上的瓜葛可言

在链表中,每一个结点的结构都包括了两部分的内容:数据域和指针域。JS 中的链表,是以嵌套的对象的形式来实现的:

{ // 数据域 val: 1, // 指针域,指向下一个结点 next: { val:2, next: ... }
} 

数据域存储的是当前结点所存储的数据值,而指针域则代表下一个结点(后继结点)的引用。 有了 next 指针来记录后继结点的引用,每一个结点至少都能知道自己后面的节点在哪,原本相互独立的结点之间就有了如下的联系:

创建链表节点

function ListNode(val) { this.val = val; this.next = null;
}
// 创造一个节点,并且节点的值为1
const node = new ListNode(1) 

在使用构造函数创建结点时,传入 val (数据域对应的值内容)、指定 next (下一个链表结点)即可:

const node1 = new ListNode(1) 
node1.next = new ListNode(2) 

经过上一步操作就创建出了一个数据域值为1,next 结点数据域值为2的链表结点:

链表的结点间关系是通过 next 指针来维系的。因此,链表元素的添加和删除操作,本质上都是在围绕 next 指针做文章。

添加节点

直接在尾部添加结点相对比较简单,我们改变一个 next 指针就行。

这里记值为2的 node 结点为 node2(假设 node2 是现在的尾部结点),值为3的 node 结点为 node3。

假如我要把 node3 添加到 node2 所在链表的尾部,直接把 node2 的 next 指针指向 node3 即可:

插入节点

如何在两个结点间插入一个结点?

由于链表有时会有头结点,这时即便你是往链表头部增加结点,其本质也是“在头结点和第一个结点之间插入一个新结点”。

大学时的计算机网络基础课,任意两结点间插入一个新结点这种类型的增加操作算是一道必考题了

我们需要变更的是前驱结点目标结点的 next 指针指向,过程如下图:

代码这样写

// 如果目标结点本来不存在,那么记得手动创建 
const node3 = new ListNode(3) 

// 把node3的 next 指针指向 node2
node3.next = node1.next

// 把node1的 next 指针指向 node3 
node1.next = node3 

删除节点

如何把刚才添加的node3节点删除?

可以直接让它的前驱结点 node1 的 next 指针跳过它、指向 node3 的后继即可:

这个过程用代码表述如下:

node1.next = node3.next 

涉及链表删除操作的题目中,重点不是定位目标结点,而是定位目标结点的前驱结点

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

MindFusion.Diagramming for JavaScript V4.2.4

MindFusion.Diagramming for JavaScript V4.2.4 现在支持使用套索工具进行缩放的多种方式。2022 年 12 月 15 日 - 15:44新版本特征 套索缩放工具- 该控件现在支持使用套索工具进行缩放的多种方式。新的“PanAndModify”行为允许您在鼠标指针悬停在某个项目上或平移视图时进行选…

HTTPS工作过程!

HTTPS了解 HTTPS 也是一个应用层协议, 是在 HTTP 协议的基础上引入了一个加密层。HTTP 协议内容都是按照文本的方式明文传输的, 这就导致在传输过程中出现一些被篡改的情况。如运营商劫持。 HTTPS工作过程 ① 既然要保证数据安全, 就需要进行 “加密”。…

【python】如何把你的python包发布出去(pip install)

python:如何把你的python包发布出去(pip install) 介绍 实际上分为两步 打包发布 我们要发布的网站是https://pypi.org/。也就是用户通过pip install XXX,就可以安装你的包。 1 通过setuptools打包 需要我们编写setup.py f…

数据库的事务

作者:~小明学编程 文章专栏:MySQL 格言:目之所及皆为回忆,心之所想皆为过往 目录 什么是事务? 事务的特性 原子性 一致性 持久性 独立性 事务之间的影响 脏读 不可重复读 幻读 数据库的隔离级别 读未提交…

kvm介绍

kvm里主要去介绍它的虚拟化技术,包括云计算的组成和云计算的背景。 kvm的运行原理,虚拟机的创建,虚拟机的生命周期管理。 云计算的定义 它不是一种技术,它是一种收费模式,就是通过互联网把一些主机的硬件&#xff0…

2021年我国企业服务市场投融资概况 技术服务单笔规模最大 早期融资笔数最多

一、企业服务投融资年度概况 据相关数据显示,2021年我国企业服务市场共发生2417笔投融资事件,其中,1753笔项目已披露融资金额。从月度分布来看,3月、6月、7月、8月和12月的融资数量均在200起以上,其中,12月…

[附源码]Python计算机毕业设计高校学生体温管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

Python实现:高斯滤波 均值滤波 中值滤波 Canny(边缘检测)PCA主成分分析 直方图规定化 Mean_Shift

Python实现:高斯滤波 均值滤波 中值滤波 Canny(边缘检测)PCA主成分分析 直方图规定化 Mean_Shift(文末附上整合这些函数的可视化界面并且已做打包处理) 1.高斯滤波(以下函数所有的图片路径为方便前来copy的同学&#…

微服务框架 SpringCloud微服务架构 多级缓存 46 JVM 进程缓存 46.4 实现进程缓存

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存46 JVM 进程缓存46.4 实现进程缓存46.4.1 实现进程缓存46 JVM 进程缓存 46.4 实现进程缓存 46.4.1 实…

Linux从入门到进阶学习(Ⅱ):Linux基础命令

目录 1 Linux目录结构 2 命令格式 3 目录切换命令 3.1 ls命令 3.2 选项与参数 3.3 目录切换 1.cd 2.pwd 4 路径 5 创建目录命令 6 文件操作命令 6.1 创建文件 6.2 查看文件 6.3 复制文件 6.4 移动文件 6.5 删除文件 1.rm命令 2.通配符 3.root用户 7 查找命…

C语言期末集训2(大一,超基础,小猫猫大课堂的配套练习)——分支结构

更新不易,麻烦多多点赞,欢迎你的提问,感谢你的转发, 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我…

分库分表 15 连问,你抗的住吗?

我们去面试的时候,几乎都会被问到分库分表。 在这里整理了分库分表的15道经典面试题,大家看完肯定会有帮助的。 1. 我们为什么需要分库分表 在分库分表之前,就需要考虑为什么需要拆分。我们做一件事,肯定是有充分理由的。所以得…

技术分享-应用列表性能优化

阅读文章大约需要10分钟 目录 1.背景 2.分析 3.优化 4.成果 背景 应用存在大量的列表和图片资源加载,如首页、喵圈、直播间广播、礼物面板等, 这些列表的性能对应用性能有着不少的影响。 分析 分析-列表架构VLayout 分析-RecycleView缓存机制 分析-RecycleVi…

【记录】Ubuntu实现逻辑卷的删除

由于我的电脑上有机械硬盘和固态硬盘,所以在之前安装的Centos7系统中,定义了逻辑卷,希望将机械硬盘和固态硬盘在逻辑上当作是统一的整体,但是正因为此操作,导致在重装系统过程中,始终无法对逻辑卷进行分区&…

m基于改进PSO粒子群优化的RBF神经网络解耦控制算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 智能控制的思想最早来自傅京孙教授[,他通过人机控制器和机器人方面的研究,首先把人工智能的自觉推理方法用于学习控制系统,将智能控制概括为自动控制和人工智能…

MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……

SysInfo主要是通过WMI来获取系统信息的,但是WMI获取的操作系统信息中没有Windows操作系统是32位还是64位的内容,所以需要另外想办法编程获取,比较常见的方法是调用Windows API函数GetNativeSystemInfo()或IsWow64Process()。之前分别用MASM32…

Spring官宣新家族成员:Spring Authorization Server

8月17日,Spring官方宣布 Spring Authorization Server 已正式脱离实验状态,并进入Spring-Project家族! 背景 Spring Authorization Server (以下简称 SAS)是 Spring 团队最新开发适配 OAuth 协议的授权服务器项目&…

【react】生命周期

组件从创建到死亡会经历一些特定的阶段 React组件中包含一系列勾子函数(生命周期回调函数)会在特定的时候调用 我们 在定义组件时,会在特定的生命周期回调函数中做特定的工作 一、旧版本的生命周期 1、初始化阶段 constructor()componentWil…

CVE-2022-22965:spring参数绑定漏洞

CVE-2022-22965 博客链接:https://www.blog.23day.site/articles/73 漏洞说明 Spring framework 是Spring 里面的一个基础开源框架,其目的是用于简化 Java 企业级应用的开发难度和开发周期,2022年3月31日,VMware Tanzu发布漏洞报告&#xff…

LabVIEW创建自定义书签管理器

LabVIEW创建自定义书签管理器 书签是一种特殊的标记机制,可以添加到VI框图中。任何以井号标签(#)开头的文本都将被LabVIEW自动识别为书签。这些可用于标记代码不同部分中的待办事项或未完成的任务。当您将主题标签添加框图注释时&#xff0c…