js实现双向链表
1.概念
上一个文章里我们已经了解到链表结构,链表的特点是长度不固定,不用担心插入新元素的时候新增位置的问题。插入一个元素的时候,只要找到插入点就可以了,不需要整体移动整个结构。
这里我们了解一下双向链表的结构。尽管从链表中头节点遍历到尾节点很容易,但是反过来,从后向前遍历就没有那么简单。通过给Node对象增加一个属性,该属性存储指向前驱节点的链接,这样就容易多了。此时祥链表中插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和后续。但是在从链表中删除节点的时候效率更高了,不需要再查找待删除节点的前驱节点了。如下图1演示了双向链表的工作原理。

图1
首先是要为Node类增加一个previouse属性,这个属性指向当前节点的前驱:
function Node(element){
this.element = element;
this.next = null;
this.previous = null;
}
双向链表的insert()方法和单项链表的类似,但是需要设置新节点的previouse属性,是其指向该节点的前驱。该方法的定义如下:

function insert(newElement , item){
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
newNode.previous = current;
current.next = newNode;
}

双向链表的删除remove()方法币单项链表的效率更高,因为不需要查找前驱节点了。首选需要在链表中找出存储待删除数据的节点,然后设置该节点的next属性,使其指向待删除节点的后续。设置该节点的后续的previouse的属性,使其指向待删除节点的前驱。如下图2展示删除节点的过程:

图2
remove()方法的定义如下:

function remove(item){
var currNode = this.find(item);
if(!(currNode.next == null)){
currNode.previous.next = currNode.next;
currNode.next.previous = currNode.previous;
currNode.next = null;
currNode.previous = null;
}
}

为了实现反向显示链表中元素的任务,需要给链表增加一个工具方法,用来查找链表中最后一个节点。findLast()方法找出链表中最后一个节点,同时免除从前往后遍历之苦。如下:

function findLast(){
var currNode = this.head;
while (!(currNode.next == null)){
currNode = currNode.next;
}
return currNode;
}

有了这个工具方法之后就,就可以很容易的写出反向显示双向链表的元素的方法,dispReverse()方法如下所示:

function dispReverse(){
var currNode = this.head;
currNode = this.findLast();
while (!(currNode.previous == null)){
document.write(currNode.element + ' ');
currNode = currNode.previous;
}
}

2.代码实现
双向链表就上面一些特性,下面是完整的代码实现和测试代码:

function Node(element){
this.element = element;
this.next = null;
this.previous = null;
}
function LList(){
this.head = new Node('head');
this.find = find;
this.insert = insert;
this.display = display;
this.remove = remove;
this.findLast = findLast;
this.dispReverse = dispReverse;
}
function dispReverse(){
var currNode = this.head;
currNode = this.findLast();
while (!(currNode.previous == null)){
document.write(currNode.element + ' ');
currNode = currNode.previous;
}
}
function findLast(){
var currNode = this.head;
while (!(currNode.next == null)){
currNode = currNode.next;
}
return currNode;
}
function remove(item){
var currNode = this.find(item);
if(!(currNode.next == null)){
currNode.previous.next = currNode.next;
currNode.next.previous = currNode.previous;
currNode.next = null;
currNode.previous = null;
}
}
function display(){
var currNode = this.head;
while (!(currNode.next == null)){
document.write(currNode.next.element + ' ');
currNode = currNode.next;
}
}
function find(item){
var currNode = this.head;
while (currNode.element != item){
currNode = currNode.next;
}
return currNode;
}
function insert(newElement , item){
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
newNode.previous = current;
current.next = newNode;
}
var cities = new LList();
cities.insert('Conway','head');
cities.insert('Russellville', 'Conway');
cities.insert('Carlisle', 'Russellville');
cities.insert('Alma' , 'Carlisle');
cities.display();
document.write('<br>');
cities.remove('Carlisle');
cities.display();
document.write('<br>');
cities.dispReverse();

js实现双向链表的更多相关文章
- js实现双向链表, 双向链表需要增加一个previous属性
双向链表, 双向链表需要增加一个previous属性 /*双向链表 * */ function Node(element) { this.element = element; this.next = ...
- 原生JS实现双向链表
1.前言 双向链表和单向链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素,另一个链向前一个元素,如下图所示: 从图中可以看到,双向链表中,在 ...
- 双向链表、双向循环链表的JS实现
关于链表简介.单链表.单向循环链表.JS中的使用以及扩充方法: 单链表.循环链表的JS实现 关于四种链表的完整封装: https://github.com/zhuwq585/Data-Structu ...
- js数据结构与算法--双向链表的实现
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接后继和直接前驱.所以,双向链表中的任意一个节点开始,都可以很方便的访问它的前驱节点和后继节点. 双向链表的实现 linke ...
- JS数据结构第三篇---双向链表和循环链表之约瑟夫问题
一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...
- 用js刷剑指offer(二叉搜索树与双向链表)
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 牛客网链接 js代码 /* function TreeNode(x) { ...
- (js描述的)数据结构[双向链表](5)
(js描述的)数据结构[双向链表](5) 一.单向链表的缺点 1.只能按顺序查找,即从上一个到下一个,不能反过来. 二.双向链表的优点 1.可以双向查找 三.双向链表的缺点 1.结构较单向链表复杂. ...
- js模拟链表---双向链表
双向链表: 每个元素,有一个 next(指向下一个元素)和一个prev(指向前一个元素) function dbLinkedList(){ var length=0; var head = null; ...
- js数据结构之链表(单链表、双向链表、循环链表)
首先,链表有以下特点: 1. 存储空间不固定,可灵活扩充 2.方便多次的插入和删除,效率较高 单链表 单链表是最常用的链表,其对数据的操作均为单项的,向后查找的. /* 链表(基于对象) 此处为单链表 ...
随机推荐
- Tomcat笔记:Tomcat的执行流程解析
Bootstrap的启动 Bootstrap的main方法先new了一个自己的对象(Bootstrap),然后用该对象主要执行了四个方法: init(); setAwait(true); load(a ...
- 如何查找SHELL的进程号并杀死
一.shell查找进程并杀死 #!/bin/sh tomcat_id=`ps -ef | grep tomcat | grep -v "grep" | awk '{print $2 ...
- Visual Studio最好用的快捷键(你最喜欢哪个)
每次在网上搜关于VS有哪些常用快捷键的时候,出来的永远是一串长的不能再长的列表,完全没体现出“常用”二字,每次看完前面几个就看不下去了,相信大家都 有这种感觉.其实我们平时用的真的只有很少的一部分,借 ...
- 「每日一码」(精品代码,质量保证)empty和undefined
将每天看到的优秀的代码或者特别的实现,记录下来 2019-2-26 empty和undefined 数组的filter,以下输出结果是什么 var arr = [1,2,3]; arr[10] = 9 ...
- Linux终端回话记录和回放工具 - asciinema使用总结
目前linux终端回放工具常见的就是asciinema和script了, 这两种工具都有那种类似于视频回放的效果.虽然这样做的代价是录制过程中需要占用一定的cpu资源以及录制后可能会因为视频文件太大而 ...
- [转]EasyUI 日期格式
本文转自:http://www.jeasyui.net/demo/512.html Different date formats are applied to different DateBox co ...
- XML Parsing Error: no element found Location: moz-nullprincipal:{23686e7a-652b-4348-92f4-7fb3575179ed} Line Number 1, Column 1:^
“Hi Insus.NET, 我有参考你下午发布的一篇<jQuery.Ajax()执行WCF Service的方法>http://www.cnblogs.com/insus/p/37278 ...
- Java基础——字符编码
一.ASII 美国(国家)信息交换标准(代)码. 计算机中只有数字,一切都是用数字表示,屏幕上显示的一个一个的字符也不例外. 一个字节可表示的数字为0-255,足以显示键盘上的所有的字符 例如. a ...
- Java基础——GUI编程(四)
继前面的,这篇主要记录菜单和文件对话框的两个小练习,来熟悉一下方法的应用,一些简单的逻辑和Swing的相关简介,以及关于GUI基础的记录. 一.创建一个菜单 import java.awt.FlowL ...
- 我的第一篇博文,开启我的Java程序人生之旅!
原文:https://blog.csdn.net/CodeYearn/article/details/89190342 自我介绍: 姓名:蔡余 性别:男 年龄:21 职业:Java开发工程师 家乡:湖 ...