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.方便多次的插入和删除,效率较高 单链表 单链表是最常用的链表,其对数据的操作均为单项的,向后查找的. /* 链表(基于对象) 此处为单链表 ...
随机推荐
- 浅尝Vue.js组件(二)
本篇目录: 插槽(Slot) 插槽内容 作用域 具名插槽 作用域插槽 独占默认插槽的缩写语法 解构插槽Prop 使用场景举例 动态插槽名 具名插槽缩写 动态组件&keep-alive 异步组件 ...
- Collections.sort()中的mergeSort归并排序
@SuppressWarnings({"unchecked", "rawtypes"}) private static void mergeSort(Objec ...
- idea @Override is not allowed when implementing interface method
转自:http://blog.csdn.net/shenya2/article/details/50460447 在编码过程发现报错:@Override is not allowed when imp ...
- 我的MQ笔记
1.安装IBM MQ 1.1.安装先决条件: (1)WebSphere Eclipse Platform V3.01 (2)为Windows域用户配置WebSphere MQ用户 1.2.安装程 ...
- BIO与NIO、AIO的区别(这个容易理解)
转自:http://blog.csdn.net/skiof007/article/details/52873421 BIO与NIO.AIO的区别(这个容易理解) IO的方式通常分为几种,同步阻塞的BI ...
- 在GridView控件内文本框实现TextChanged事件
本篇是教你实现GridView控件内的TextBox文本框实现自身的TextChanged事件.由于某些功能的需求,GridView控件内嵌TextBox,当TextBox值发生变化时,触发TextC ...
- WPF备忘录(6)WPF实现打印功能
在WPF 中可以通过PrintDialog 类方便的实现应用程序打印功能,本文将使用一个简单实例进行演示.首先在VS中编辑一个图形(如下图所示). 将需要打印的内容放入同一个<Canvas> ...
- PHP错误集锦
错误原因:分页数据不够,使用了缓存,但是model类中又没有添加缓存.解决办法:在model类中添加缓存,内容结束时清空缓存.
- Word文档中多个编号放同一行的方法(非技术)
最近在帮公司出应届生校招面试题,为了方便,选择题部分的答案用了Word的[编号]功能!如下截图所示: 这么简短的四个答案这么竖着放很占空间(打印时也很浪纸张),能不能让它们全部横放在同一行,或两两一组 ...
- python-享元模式
源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 如果一个软件系统在运行时所创建的相同或相似对象数量太多,将导致运行代价过高,带来 ...