JS 数据结构双向链表

【JS数据结构】双向链表 一. 认识双向链表 1.单向链表 1.1 概念 1.2 实现的原理 1.3 缺点 2.双向链表 2.1 概念 2.2 实现的原理 2.3 缺点 2.4 双向连接的特点图解 二.双向链表的创建 1.创建一个双向链表的类 2.双向链表的常见操作 2.1append(element)尾部追加数据 2.2 将链表转成字符串形式 2.3 insert(position, element)任意位置插入 2.4 get(position)获取对应位置的元素 2.5 indexOf(el 阅读详情

认识双向链表

单项链表:

只能从头遍历到尾或者从尾部遍历到头(一般从头到尾)

也就是链表相连的过程是单向的,实现的原理是上一个链表中有一个指向下一个的引用

单向链表的缺点:

        我们可以轻松的到达下一个节点,但是回到前一个节点很难。但是,在实际开发中,经常会遇到需要回到上一个节点的情况

双向链表:

每次在插入或删除的时候某个节点,需要处理四个节点的引用,而不是两个,也就是实现起来比较困难一点

并且相当于单项链表,必然占用内存空间更大一些

但是这些缺点和我们使用起来的方便程度相比,是微不足道的

双向链接的图解

 双向链表的创建

我们来创建一个双向链表的类

// 创建双向链表的构造函数
function DoublyLinkedList() {
    // 创建节点构造函数
    function Node(element) {
        this.element = element
        this.next = null
        this.prev = null // 新添加的
    }

    // 定义属性
    this.length = 0
    this.head = null
    this.tail = null // 新添加的

    // 定义相关操作方法
}

操作双向链表

尾部追加数据

// 在尾部追加数据
DoublyLinkedList.prototype.append = function (element) {
    // 1.根据元素创建节点
    var newNode = new Node(element)

    // 2.判断列表是否为空列表
    if (this.head == null) {
        this.head = newNode
        this.tail = newNode
    } else {
        this.tail.next = newNode
        newNode.prev = this.tail
        this.tail = newNode
    }
    
    // 3.length+1
    this.length++
}

代码解析:

代码1部分不用多讲, 还是通过元素创建新的节点.

代码2部分相比之前有一些复杂, 但是还是两种情况.

情况一: 链表原来为空

链表中原来如果没有数据, 那么直接让head和tail指向这个新的节点即可.

情况二: 链表中已经存在数据

因为我们是要将数据默认追加到尾部, 所以这个变得也很简单.

首先tail中的next之前指向的是null. 现在应该指向新的节点newNode: this.tail.next = newNode

因为是双向链表, 新节点的next/tail目前都是null. 但是作为最后一个节点, 需要有一个指向前一个节点的引用. 所以这里我们需要newNode.prev = this.tail

因为目前newNod已经变成了最后的节点, 所以this.tail属性的引用应该指向最后: this.tail = newNode即可

代码3部分不用多做解析, length需要+1

正向反向遍历

forwardString: 正向遍历转成字符串的方法

reverseString: 反向遍历转成字符串的方法

toString: 正向遍历转成字符串的方法

方法的相关实现

// 正向遍历的方法
DoublyLinkedList.prototype.forwardString = function () {
    var current = this.head
    var forwardStr = ""
    
    while (current) {
        forwardStr += "," + current.element
        current = current.next
    }
    
    return forwardStr.slice(1)
}

// 反向遍历的方法
DoublyLinkedList.prototype.reverseString = function () {
    var current = this.tail
    var reverseStr = ""
    
    while (current) {
        reverseStr += "," + current.element
        current = current.prev
    }
    
    return reverseStr.slice(1)
}

// 实现toString方法
DoublyLinkedList.prototype.toString = function () {
    return this.forwardString()
}

完成上面的代码后,测试 append方法

// 1.创建双向链表对象
var list = new DoublyLinkedList()

// 2.追加元素
list.append("abc")
list.append("cba")
list.append("nba")
list.append("mba")

// 3.获取所有的遍历结果
alert(list.forwardString()) // abc,cba,nba,mba
alert(list.reverseString()) // mba,nba,cba,abc
alert(list) // abc,cba,nba,mba

任意位置插入

// 在任意位置插入数据
DoublyLinkedList.prototype.insert = function (position, element) {
    // 1.判断越界的问题
    if (position < 0 || position > this.length) return false

    // 2.创建新的节点
    var newNode = new Node(element)

    // 3.判断插入的位置
    if (position === 0) { // 在第一个位置插入数据
        // 判断链表是否为空
        if (this.head == null) {
            this.head = newNode
            this.tail = newNode
        } else {
            this.head.prev = newNode
            newNode.next = this.head
            this.head = newNode
        }
    } else if (position === this.length) { // 插入到最后的情况
        // 思考: 这种情况是否需要判断链表为空的情况呢? 答案是不需要, 为什么?
        this.tail.next = newNode
        newNode.prev = this.tail
        this.tail = newNode
    } else { // 在中间位置插入数据
        // 定义属性
        var index = 0
        var current = this.head
        var previous = null
        
        // 查找正确的位置
        while (index++ < position) {
            previous = current
            current = current.next
        }
        
        // 交换节点的指向顺序
        newNode.next = current
        newNode.prev = previous
        current.prev = newNode
        previous.next = newNode
    }
    
    // 4.length+1
    this.length++
    
    return true
}

测试该方法

// 4.insert方法测试
list.insert(0, "100")
list.insert(2, "200")
list.insert(6, "300")
alert(list) // 100,abc,200,cba,nba,mba,300

位置移除数据

// 根据位置删除对应的元素
DoublyLinkedList.prototype.removeAt = function (position) {
    // 1.判断越界的问题
    if (position < 0 || position >= this.length) return null

    // 2.判断移除的位置
    var current = this.head
    if (position === 0) {
        if (this.length == 1) {
            this.head = null
            this.tail = null
        } else {
            this.head = this.head.next
            this.head.prev = null
        }
    } else if (position === this.length -1) {
        current = this.tail
        this.tail = this.tail.prev
        this.tail.next = null
    } else {
        var index = 0
        var previous = null

        while (index++ < position) {
            previous = current
            current = current.next
        }

        previous.next = current.next
        current.next.prev = previous
    }

    // 3.length-1
    this.length--

    return current.element
}

获取元素位置

// 根据元素获取在链表中的位置
DoublyLinkedList.prototype.indexOf = function (element) {
    // 1.定义变量保存信息
    var current = this.head
    var index = 0

    // 2.查找正确的信息
    while (current) {
        if (current.element === element) {
            return index
        }
        index++
        current = current.next
    }

    // 3.来到这个位置, 说明没有找到, 则返回-1
    return -1
}

数据结构JavaScript——双向链表、双向循环链表 双向链表的JS实现 阅读详情

相关推荐

lijst:JavaScript 双向链表实现

列表 JavaScript 双向链表实现 当前 API 状态: lijst Capacity ✓ # empty() ✓ # length Element access ✓ # front() ✓ # back() Modifiers ✓ # assign() ✓ # pushFront() ✓ # popFront() ✓ # push() #pushBack() ✓ # pop() #popBack() - # insert() ✓ # erase() - # swap() - # resize() ✓ # clear() Operations - # splice()

JavaScript实现双向链表

JavaScript实现双向链表 JavaScript实现双向链表 一、双向链表简介 双向链表:既可以从头遍历到尾,又可以从尾遍历到头。也就是说链表连接的过程是双向的,它的实现原理是:一个节点既有向前连接的引用,也有一个向后连接的引用。 双向链表的缺点: 每次在插入或删除某个节点时,都需要处理四个引用,而不是两个,实现起来会困难些; 相对于单向链表,所占内存空间更大一些; 但是,相对于双向链表的便利性而言,这些缺点微不足道。 双向链表的结构: 双向链表不仅有head指针指向第一个节点,而且有tail

雨的印记的博客 793

从“Hello World”到区域赛银牌:我的ACM算法打怪升级全记录(附各阶段工具包)

本文记录了作者从编程新手到ACM区域赛银牌获得者的完整学习历程,详细分享了各阶段的算法学习路线、刷题策略和实战经验。涵盖从基础算法到动态规划的系统训练方法,并附赠经过竞赛检验的工具包和资源清单,为算法竞赛爱好者提供实用参考。

weixin_29201859的博客 123

【数据结构与算法】JavaScript实现双向链表

双向链表:既可以从头遍历到尾,又可以从尾遍历到头。也就是说链表连接的过程是双向的,它的实现原理是:一个节点既有向前连接的引用,也有一个向后连接的引用。每次在插入或删除某个节点时,都需要处理四个引用,而不是两个,实现起来会困难些;相对于单向链表,所占内存空间更大一些;但是,相对于双向链表的便利性而言,这些缺点微不足道。双向链表不仅有head指针指向第一个节点,而且有tail指针指向最后一个节点;item储存数据、prev指向前一个节点、next指向后一个节点;

一个前端开发者 494

从ST转国产ARM必看:GD32/APM32等5款芯片的SWD下载全攻略(含CH32特殊处理)

本文为从STM32转向国产ARM芯片的开发者提供了详细的SWD下载调试指南。针对GD32F103C8T6、APM32F103C8T6等五款热门国产芯片,详细说明了如何利用已有的ST-Link工具和Keil MDK环境进行程序烧录,并特别介绍了CH32F103芯片所需的独立器件库安装等特殊处理方法,帮助开发者实现平滑迁移,提升开发效率。

weixin_29195615的博客 278

逆向分析第一步:如何从HEX文件‘还原’出单片机的原始程序与数据?

本文详细解析了如何从HEX文件逆向分析出单片机的原始程序与数据,涵盖了固件逆向的底层逻辑与实践。通过介绍HEX文件的结构、内存映像重建技术以及专业工具链的使用,帮助读者掌握从十六进制数据到可执行代码的完整流程,适用于嵌入式系统开发和逆向工程领域。

weixin_29745609的博客 317

JS数据结构与算法之双向链表结构

JS数据结构与算法——双向链表结构

weixin_52479225的博客 413

从透射谱到能量分布:用Rsoft破解光纤光栅耦合模式的3个关键技巧

本文面向光通信工程师与研究者,分享了利用Rsoft软件深入分析光纤光栅耦合模式的三个关键技巧。通过配置场监视器观察XY截面能量分布、利用传播动画追踪动态过程,并结合模式求解器精准判定相位匹配,帮助用户超越透射谱分析,直观可视化能量从纤芯到包层的耦合与流动,从而优化器件设计。

weixin_29290963的博客 422

js数据结构学习--双向链表

5.双向链表 双向链表优点 即可以从头遍历到尾,也可以从尾遍历到头 一个节点既有向前连接的引用,也有一个向后连接的引用 双向链表缺点 每次插入或删除某个节点时,需要处理四个引用 相对于单向链表,所占内存空间更大 5.1双向链表的特点 使用一个head指向头部,一个tail指向尾部 每个节点都由三部分组成:前一个节点指针(prev)/保存的元素(item)/后一个节点的指针(next) 双向链表第一个节点的prev为null,最后的节点

qq_44998582的博客 250

使用Mask2Former和X-Decoder训练自定义数据集及结果复现报告

本报告记录了使用MMDetection框架中的Mask2Former和X-Decoder模型在自定义数据集上的训练过程。报告包含环境配置、数据集准备、模型训练与优化(解决了Mask2Former的PQ值异常问题)、性能评估等关键环节。详细展示了从数据集转换(将客户提供的COCO格式数据适配MMDetection框架)、配置文件修改、到最终模型训练和评估的全流程。特别针对Mask2Former训练中的PQ值异常问题提供了解决方案,并对比了两种模型在自定义数据集上的表现。报告还包含完整的代码实现和技术细节。

huanghm88的专栏 1098

OGRE 3D----2. QGRE + QQuickView

将 OGRE(面向对象图形渲染引擎)集成到使用 QQuickView 的 Qt Quick 应用程序中,可以在现代灵活的 UI 框架中提供强大的 3D 渲染功能。本文将指导您如何在 QQuickView 环境中设置 OGRE。

charce_you的专栏 914

JS数据结构(6)——双向链表

JS数据结构(6)——双向链表 1.什么是双向链表? 单向链表 要知道什么是双向链表,我们首先得了解单向链表。 单向链表的详细解释在这里: JS单向链表 单向链表的特点: 只能从头遍历到尾 链表的连接过程是单向的 实现的原理是上一个链表结点中有一个指向下一个结点的next 单向链表的结构: 单向节点的缺点: 可以轻松到达下一个节点,但是回到前一个节点是非常困难的。 双向链表 双向链表的特点: 既可以从头遍历到尾,也可以从尾遍历到头 链表连接的过程时双向的 实现原理是一个链表结点,既有指向前一个

echomsy的博客 240

解决Google Play签名问题:Android App Bundle上传指南

摘要:本文分享了解决Android App Bundle上传至Google Play时遇到的签名问题的经验。当使用pepk.jar工具加密私钥时,出现"NoSuchAlgorithmException"错误。解决方案包括:确保使用JDK 11+版本、更新pepk.jar工具、验证密钥库信息,并提供详细命令行示例。通过升级开发环境和正确配置签名参数,最终成功生成加密密钥文件。文章为开发者提供了实用的技术参考,强调耐心排查问题的重要性。(149字)

m0_62153576的博客 147

JavaScript数据结构(双向链表)

JavaScript数据结构(双向链表)双向链表&单向链表双向链表常见的操作JavaScript代码双向链表的封装 双向链表&单向链表 单向链表:只能从一端向另一端遍历 双向链表:既可以从头部向尾部开始遍历,也可以熊尾部向头部开始遍历。 一个head指针指向第一个节点,一个tail指针指向最后一个节点。 当没有节点时,head指针和tail指针都指向NULL。 双向链表常见的操作 append(element) 向链表尾部追加一个新元素。 insert(position, element

nanxing的博客 760

思远耳机充电芯片-SY5501

BES2700ZP-本文档介绍了思远耳机充电芯片SY5501的使用方法,包括芯片引脚功能说明(VCC、IRQ、RST等)、通信机制(VIN引脚的双重作用)以及相关注意事项。提供了代码片段、调试日志和电路图作为参考,并列出了待解决的问题清单。该芯片需要配合特定充电仓使用,支持私有协议和用户自定义通信功能。

云淡风轻 123

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JavaScript 数据结构之双向链表

//节点类 class Node{ constructor(data){ this.data = data; //表示节点的数据域 this.prev = null; //指针域:指向当前节点的上一个节点 this.next = null; //指针域:指向当前节点的下一个节点 } } //双向链表类 class DoubleLinkList { constructor() { this.size = 0; //单链

weixin_49087505的博客 642

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

(js描述的)数据结构[双向链表](5)

(js描述的)数据结构[双向链表](5) 一.单向链表的缺点 1.只能按顺序查找,即从上一个到下一个,不能反过来。 二.双向链表的优点 1.可以双向查找 三.双向链表的缺点 1.结构较单向链表复杂。 2.占用内存比单项链表多。 四.双向链表的结构 五.双向链表的代码实现 function DoublyLinkedList() { // 内部节点类 ...

面向许三多编程 156

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

javaScript数据结构与算法之双向链表的实现

javaScript数据结构与算法之双向链表的实现引言快捷通道原理完整javaScript代码完整typeScript代码结语 引言 这篇文章写之前其实双向链表的实现已经写了好几天了,期间反复修改过,最后感觉自己写的复杂了,又删除了很多方法,只保留了一些基本的方法,最终完成了双向链表的实现 快捷通道 上一篇:javaScript数据结构与算法之单向链表的实现. 下一篇:暂无 原理 双向链表原理还是离散节点的连接,不同的是单向链表是有next指向下一个节点,而双向链表在有next的情况下,还有一个last指向

u014050961的博客 259

JavaScript ES6语法数据结构(二)—— 双向链表

文章目录双向链表双向链表的定义节点链式结构双向链表的基本操作前插节点尾插节点删除头节点删除尾节点删除值为value的节点链表转换为节点数组数组转链表复杂度时间复杂度空间复杂度总结 双向链表 双向链表是链表中的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。 双向链表的节点数据由下面三部分组成: 上...

MayanDev 689

JavaScript实现数据结构的栈、队列和双向链表

数据结构中的栈、队列和链表应该是最基础的了,还有像是图、树、二叉树、最优二叉树/解等等也很重要,前端也要会数据结构是我没想到的,总结一下用JavaScript实现数据结构中的栈、队列和链表中的双向链表。

adiynil 228

数据结构与算法五(js 实现双向链表)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>双向链表</title> </head> <body> <script> function DoublyLinkedList...

ZhaiAlan的博客 242

javascript实现数据结构(双向链表)

前言 数据结构是一种存储数据之间的逻辑结构, 合适的数据结构可以带来更高的运行效率和存储效率, 与相应解决实际问题算法的适应性也就越高, 算法和数据结构往往是互不分开的。 离开了算法,数据结构就显得毫无意义,而没有了数据结构,算法就没有实现的条件。 什么是双向链表 之前讲了单向链表,简单来说就是单向的只有一个出生点在车头; 双向多了一个出生点在车尾。 function DoubelLinkedList(){ this.head = null this.tail = null this.length

kyyius的博客 136

javascript数据结构和算法——链表,双向链表

javascript数据结构和算法——链表,双向链表 一、单向链表 <script> class Node { constructor(element) { this.element = element; this.next = null; } } class linkList { constructor() { this.head = null; this.length = 0; } // 向链表中添加元素 append(element

weixin_47450807的博客 254

JavaScript 数据结构与算法(七)双向链表

JavaScript 数据结构与算法(七)双向链表 单向链表和双向链表 单向链表 只能从头遍历到尾或者从尾遍历到头(一般从头到尾)。 链表相连的过程是单向的,实现原理是上一个节点中有指向下一个节点的引用。 单向链表有一个比较明显的缺点:可以轻松到达下一个节点,但回到前一个节点很难,在实际开发中, 经常会遇到需要回到上一个节点的情况。 双向链表 既可以从头遍历到尾,也可以从尾遍历到头。 链表相连的过程是双向的。实现原理是一个节点既有向前连接的引用,也有一个向后连接的引用。 双向链表可以有效的解决单向链表

weixin_42572968的博客 266

数据结构与算法4:用JavaScript 实现 双向链表 结构

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 特点 : 可以用一个head 和一个tail 分别指向头和尾的节点 每个节点都由三部分组成:前一个节点的指针(prev)/保存元素(item)/后一个节点的指针(next) 双向链表的第一个节点的prev是null 双向链表的最后节点的next是null 常用方法: append(data) 追加元素

Asdas_的博客 356
上一篇: JS 数据结构 链表
下一篇: 数据结构-集合结构
Ax3_28
博客等级 码龄4年 60粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值