[js] 请使用 js 实现一个双向链表

[js] 请使用 js 实现一个双向链表

链表结构是我们在面试中经常会被问起的较为基础的数据结构问题,起初学习数据结构使用的是C++语言,最近在做前端面试题的过程中没碰到了需要用js实现双链表的需求,百度出来的文章发现可很多错误,于是索性自己重新写了,并且列出了一些错误点,这里给大家较为详细的一步步看一下实现思想和步骤,相较于C++语言,js的实现可以说是很简单了,不需要创建繁琐的对象,更加直观易懂;
首先我们来看一下双向链表的结构图:
在这里插入图片描述
每个结点包含三部分,指向前一个结点的指针(pre),指向后一个节点的指针(next),以及自己的数据部分(element),于是我们就可以先写出结点对象

function Node:定义结点对象

function Node(element) {this.element = elementthis.next = nullthis.previous = null
}

然后我们开始实现插入链表的算法
在这里插入图片描述

(声明)下面函数中的this是我们最后初始化链表的实例,这里大家不要疑惑。可以拉到最下面我们初始化链表那里,相信你会明白呦

**`function insert`:插入节点**function insert(newelement, currentelement) {var newNode = new Node(newelement)var currentNode = this.find(currentelement)if (currentNode === 'error') {console.log('无法插入,要插入节点不存在')return}if (currentNode.next != null) {newNode.next = currentNode.nextcurrentNode.next = newNodenewNode.previous = currentNodenewNode.next.previous = newNode} else {currentNode.next = newNodenewNode.previous = currentNode}
}

function find:找到插入位置

function find(element) {var currentNode = this.headwhile (currentNode.element != element) {/*如果找到最后一个节点还没有找到我们的插入点,那么我们就会返回错误*/if (currentNode.next == null) {console.log('can not find this node; maybe not have this node')return 'error'}currentNode = currentNode.next}return currentNode
}

接下来是移除结点的实现,如果看懂了插入节点的实现,那么移除就会很简单了,相信大家都可以很快明白,这里就直接贴出实现代码;

function remove:移除一个结点function remove(element) {var currentNode = this.find(element)if (currentNode === 'error') {console.log('要移除节点不存在')return}/*首先是不是头尾节点的情况*/if (currentNode.next != null && currentNode.previous != null) {currentNode.previous.next = currentNode.nextcurrentNode.next.previous = currentNode.previouscurrentNode.next = nullcurrentNode.previous = null} else if (currentNode.previous == null) {/*当是头节点的时候*/this.head = currentNode.nextcurrentNode.next.previous = nullcurrentNode.next = null} else if (currentNode.next == null) {/*当是尾节点的时候 */currentNode.previous.next = nullcurrentNode.previous = null}
}

截止到这里我们基本功能已经有了,下面使我们根据自己需要可以自定义一些其他函数

function lastNode:找到最后一个节点function lastNode() {var head = this.headwhile (head.next != null) {head = head.next}return head     //这里head在尾节点的位置
}
function append:将要添加的结点放在链表末尾function append(element) {var lastnode = this.lastNode()var newNode = new Node(element)lastnode.next = newNodenewNode.previous = lastnode
}
function showlist:将链表所有的结点打印出来function showlist() {var head = this.headdo {console.log(head.element)head = head.next} while (head != null)// 大家可以看一下下面注释内容存在什么问题,留给大家思考一下// while (head.next != null) {//   console.log(head.element)//   head = head.next// }
}

接下来是对链表进行初始化,这也是上述函数中所有this所代表的实例

function initlist:初始化链表,并将所有方法注册到链表中

function initlist() {this.head = new Node('one')this.find = findthis.insert = insertthis.remove = removethis.showlist = showlistthis.lastNode = lastNodethis.append = append
}var list = new initlist()
list.insert('two', 'one')
list.insert('four', 'two')
list.insert('three', 'two')// console.log(list.head.next)
list.showlist()
list.append('A')
list.append('B')
list.insert('B2', 'B')
list.showlist()
console.log(list.lastNode())
// list.remove('one')
// list.showlist()
console.log(list.find('A').previous)
// console.log(list.find('four').previous)
// console.log(list.head.element)

下面是运行结果:
在这里插入图片描述
源码:

function Node(element) {this.element = elementthis.next = nullthis.previous = null
}
function find(element) {var currentNode = this.headwhile (currentNode.element != element) {if (currentNode.next == null) {console.log('can not find this node; maybe not have this node')return 'error'}currentNode = currentNode.next}return currentNode
}
function insert(newelement, currentelement) {var newNode = new Node(newelement)var currentNode = this.find(currentelement)if (currentNode === 'error') {console.log('无法插入,要插入节点不存在')return}if (currentNode.next != null) {newNode.next = currentNode.nextcurrentNode.next = newNodenewNode.previous = currentNodenewNode.next.previous = newNode} else {currentNode.next = newNodenewNode.previous = currentNode}
}
function remove(element) {var currentNode = this.find(element)if (currentNode === 'error') {console.log('要移除节点不存在')return}/*首先是不是头尾节点的情况*/if (currentNode.next != null && currentNode.previous != null) {currentNode.previous.next = currentNode.nextcurrentNode.next.previous = currentNode.previouscurrentNode.next = nullcurrentNode.previous = null} else if (currentNode.previous == null) {/*当是头节点的时候*/this.head = currentNode.nextcurrentNode.next.previous = nullcurrentNode.next = null} else if (currentNode.next == null) {/*当是尾节点的时候 */currentNode.previous.next = nullcurrentNode.previous = null}
}
function showlist() {var head = this.headdo {console.log(head.element)head = head.next} while (head != null)// while (head.next != null) {//   console.log(head.element)//   head = head.next// }
}
function initlist() {this.head = new Node('one')this.find = findthis.insert = insertthis.remove = removethis.showlist = showlistthis.lastNode = lastNodethis.append = append
}
function append(element) {var lastnode = this.lastNode()var newNode = new Node(element)lastnode.next = newNodenewNode.previous = lastnode
}
function lastNode() {var head = this.headwhile (head.next != null) {head = head.next}return head
}
var list = new initlist()
list.insert('two', 'one')
list.insert('four', 'two')
list.insert('three', 'two')// console.log(list.head.next)
list.showlist()
list.append('A')
list.append('B')
list.insert('B2', 'B')
list.showlist()
console.log(list.lastNode())
// list.remove('one')
// list.showlist()
console.log(list.find('A').previous)
// console.log(list.find('four').previous)
// console.log(list.head.element)

个人简介

我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,
但坚持一定很酷。欢迎大家一起讨论

主目录

与歌谣一起通关前端面试题

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

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

相关文章

MacOS中Nginx的安装「借助Homebrew」

本文Nginx的安装借助于Homebrew; 1、Homebrew2、Nginx安装 1、Homebrew 如果你已经安装过Homebrew了,那么你可以跳过这一步,直接进行Nginx安装步骤; Homebrew是一款MacOS平台下的软件包管理工具,拥有安装、卸载、更新、…

03、动态代理--CGLib引入增强

package com.offer.note.Java基础.动态代理.CGLib引入增强;public interface Browser {void visitInternet(); } package com.offer.note.Java基础.动态代理.CGLib引入增强;/*** 目标类:被代理类** author: xueguanfeng* date: 2018-05-15 09:57*/ public class Chr…

[js] ajax请求地址只支持http/https吗?能做到让它支持rtmp://等其它自定义协议吗 ?

[js] ajax请求地址只支持http/https吗?能做到让它支持rtmp://等其它自定义协议吗 ? ajax只支持http/https协议, 可以通过自定义http头来间接支持自定义协议个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易&#xf…

面试必备:HashMap底层数据结构?jdk1.8算法优化,hash冲突,扩容等问题

面试必备系列不会长篇理论求证&#xff0c;直接上答案&#xff0c;仅供参考&#xff0c;不喜勿喷。 1、能说说HashMap的底层原理吗&#xff1f; HashMap<String,String> map new HashMap<String,String>(); map.put(“key”,”value”); [<key1,value1>,<…

[js] 请写一个性能最好的深度克隆对象的方法

[js] 请写一个性能最好的深度克隆对象的方法 const deepClone (obj) > {const copy obj instance Array ? [] : {};for (let key in obj) {if (obj.hasOwnProperty(key)) {copy[key] typeof obj[key] object ? deepClone(obj[key]) : obj[key]}} return copy; }个人简…

快速下载||AnotherRedisDesktopManagerMedis-Redis可视化工具

尽管是在Gitee上下载这款软件&#xff0c;网速仍然是非常的慢&#xff0c;不知道是不是我的网络问题。 提供一份我的下载链接 MacOS&#xff1a;Another.Redis.Desktop.Manager.1.3.1.dmg Windows&#xff1a;Another.Redis.Desktop.Manager.1.3.1.exe 也许你还想试试Medis Mac…

[js] 使用ajax请求真的不安全吗?为什么?

[js] 使用ajax请求真的不安全吗&#xff1f;为什么&#xff1f; AJAX是发送HTTP请求的一种方式&#xff0c;只不过浏览器给它加了一个同源策略而已。 所以从这一点可以得出一个结论&#xff1a;AJAX本质上安全性和HTTP请求一样个人简介 我是歌谣&#xff0c;欢迎和大家一起交…

面试必备:synchronized的底层原理?

最近更新的XX必备系列适合直接背答案&#xff0c;不深究&#xff0c;不喜勿喷。 你能说简单说一下synchronize吗&#xff1f; 可别真简单一句话就说完了呀~ 参考回答&#xff1a; synchronize是java中的关键字&#xff0c;可以用来修饰实例方法、静态方法、还有代码块&#xff…

hadoop fs 命令详解

转载: https://blog.csdn.net/bgk083/article/details/49454209转载于:https://www.cnblogs.com/water-green/p/9050122.html

数组追加数组,小程序数组里面追加数组如何操作?

由于写错小程序生命周期函数方法名称「onLoad > onload」&#xff0c;一直以为自己用错了push… 需求描述 var arr[];var value [ a,b,c,d ]; 已有数组arr&#xff0c;获取的数据形式为数组value&#xff0c;需要将value追加值arr数组中&#xff0c;即[[],[]] 尝试过程 1、…

[js] 你有使用过pjax吗?它的原理是什么?

[js] 你有使用过pjax吗&#xff1f;它的原理是什么&#xff1f; pushState ajax pjax个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

Python3回文相关算法小结

[本文出自天外归云的博客园] 总结一下关于回文相关的算法&#xff1a; 判断字符串本身是否是回文返回字符串中的所有子串找到字符串中包含的所有回文判断字符串中是否包含回文将字符串变成一个不包含回文的字符串代码如下&#xff1a; # 判断字符串本身是否是回文 def is_huiwe…

面试必备:CAS无锁机制

CAS无锁机制原理&#xff0c;面试高频问题之一&#xff0c;其实&#xff0c;日常开发中并不会直接使用CAS无锁机制&#xff0c;都是通过一系列封装好的工具类来使用&#xff0c; 说不定面试官不提问&#xff0c;都不知道有这么个东西存在。 1、能说一下你对CAS的理解吗&#xf…

[js] 根据元素ID遍历树形结构,查找到所有父元素ID

[js] 根据元素ID遍历树形结构&#xff0c;查找到所有父元素ID var list [{ "orgId": 1, "orgName": "校长办公室1", "parentId": 0 },{ "orgId": 2, "orgName": "校长办公室2", "parentId"…

安装oracle和plsql心得

最近给两台裸机安装oracle&#xff0c;plsql&#xff0c;java运行环境等相关。从中分享一些小心得。 1.oracle安装&#xff0c;基本都是安装ORACLE11g的&#xff0c;中途遇到报错了是因为64位windows系统&#xff0c;需要重新拷贝对应文件夹到对应文件下。 2.plsql安装的话&…

[js] 举例说明Object.defineProperty会在什么情况下造成循环引用导致栈溢出?

[js] 举例说明Object.defineProperty会在什么情况下造成循环引用导致栈溢出&#xff1f; var data {count: 1,value: 2 } Object.defineProperty(data, count, {enumerable: true,configurable: true,get: function () {console.log(你访问了count, this.count); // 循环读取…

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})注解作用

有小伙伴在群里问到对 SpringBootApplication(exclude { DataSourceAutoConfiguration.class}) 有点疑惑&#xff0c;故记之。 exclude&#xff0c;排除此类的AutoConfig&#xff0c;即禁止 SpringBoot 自动注入数据源配置&#xff0c;怎么讲&#xff1f; DataSourceAutoConfi…

[js] 写一个方法,当给定数字位数不足8位时,则在左边补充0以补足8位数的方法

[js] 写一个方法&#xff0c;当给定数字位数不足8位时&#xff0c;则在左边补充0以补足8位数的方法 function padNumber(n, targetLen, placeholder) {const arr ("" n).split("");const diff arr.length - targetLen;if (diff < 0) {return Array(…

小程序json字符串取值问题,怎么取出来的是undefined,eval函数不能用?

1、后端返回的值 "{\"msg\":\"InvalidParameterValue.NoFaceInPhoto-图片中没有人脸。\",\"code\":500}” 关于为何会返回如上json字符串的场景&#xff1a;文件上传「声明了Content-Type」 wx.uploadFile({ url: common.apiServerwx/user…

asp.net mvc 自定义全局过滤器 验证用户是否登录

一般具有用户模块的系统都需要对用户是否登录进行验证&#xff0c;如果用户登录了就可以继续操作&#xff0c;否则退回用户的登录页面 对于这样的需求我们可以通过自定义一个独立的方法来完成验证的操作&#xff0c;但是这样代码的重复率就大大提高了 对于这样的需求&#xff0…