1、链表的基本介绍

数组不总是组织数据的最佳数据结构,在很多编程语言中,数组的长度是固定的,所以当数组已被数据填满时,再要加入新的元素就会非常困难。在数组中,添加和删除元素也很麻烦,因为需要将数组中的其他元素向前或向后平移。

链表是由一组节点组成的集合。每个节点都使用一个对象的引用指向它的后继。许多链表的实现都在链表最前面有一个特殊节点,叫做头节点。如下图:

2、链表的实现

2.1、基于对象的链表的实现

Node 类用来表示节点,包含两个属性:element 用来保存节点上的数据,next 用来保存指向下一个节点的链接。

  1. function Node(element) {
  2.   this.element = element;
  3.   this.next = null;
  4. }

LList 类提供了对链表进行操作的方法。该类的功能包括插入删除节点、在列表中查找给定的值。

  1. function LList() {
  2.   this.head = new Node("head");
  3.   this.find = find;
  4.   this.insert = insert;
  5.   this.display = display;
  6.   this.findPrevious = findPrevious;
  7.   this.remove = remove;
  8. }

find() 方法遍历链表,查找给定数据。如果找到数据,该方法就返回保存该数据的节点。如果查找成功,该方法返回包含该数据的节点;否则,返回 null。

  1. function find(item) {
  2.   var currNode = this.head;
  3.   while (currNode.element != item) {
  4.     currNode = currNode.next;
  5.   }
  6.   return currNode;
  7. }

insert() 方法在一个已知节点后面插入元素

  1. function insert(newElement, item) {
  2.   var newNode = new Node(newElement);
  3.   var current = this.find(item);
  4.   newNode.next = current.next;
  5.   current.next = newNode;
  6. }

display() 方法用来显示链表中的元素

  1. function display() {
  2.   var currNode = this.head;
  3.   while (!(currNode.next == null)) {
  4.     print(currNode.next.element);
  5.     currNode = currNode.next;
  6.   }
  7. }

findPrevious() 方法找到待删除节点前面的节点。找到这个节点后,修改它的 next 属性,使其不再指向待删除节点,而是指向待删除节点的下一个节点。

  1. function findPrevious(item) {
  2.   var currNode = this.head;
  3.   while (!(currNode.next == null) && (currNode.next.element != item)) {
  4.     currNode = currNode.next;
  5.   }
  6.   return currNode;
  7. }

remove() 方法从链表中删除节点。

  1. function remove(item) {
  2.   var prevNode = this.findPrevious(item);
  3.   if (!(prevNode.next == null)) {
  4.     prevNode.next = prevNode.next.next;
  5.   }
  6. }

2.2、双向链表

给 Node 对象增加一个属性,该属性存储指向前驱节点的链接,这使得链表从后向前遍历变得简单

  1. function Node(element) {
  2.   this.element = element;
  3.   this.next = null;
  4.   this.previous = null;
  5. }

insert() 方法

  1. function insert(newElement, item) {
  2.   var newNode = new Node(newElement);
  3.   var current = this.find(item);
  4.   newNode.next = current.next;
      current.next.previous = newNode;
  5.   newNode.previous = current;
  6.   current.next = newNode;
  7. }

remove() 方法比单向链表的效率更高,因为不需要再查找前驱节点。

  1. function remove(item) {
  2.   var currNode = this.find(item);
  3.   if (!(currNode.next == null)) {
  4.     currNode.previous.next = currNode.next;
  5.     currNode.next.previous = currNode.previous;
  6.     currNode.next = null;
  7.     currNode.previous = null;
  8.   }else {
  9.     currNode.previous.next = null;
  10.     currNode.next = null;
  11.     currNode.previous = null;
  12.   }
  13. }

findLast() 方法查找链表中的最后一个节点,避免了从前往后遍历链表

  1. function findLast() {
  2.   var currNode = this.head;
  3.   while (!(currNode.next == null)) {
  4.     currNode = currNode.next;
  5.   }
  6.   return currNode;
  7. }

dispReverse() 方法反序显示双向链表中的元素。

  1. function dispReverse() {
  2.   var currNode = this.head;
  3.   currNode = this.findLast();
  4.   while (!(currNode.previous == null)) {
  5.     console.log(currNode.element);
  6.     currNode = currNode.previous;
  7.   }
  8. }

2.3、循环链表

循环链表和单向链表相似,节点类型都是一样的。唯一的区别是,在创建循环链表时,让其头节点的 next 属性指向它本身,即链表的尾节点指向头节点,形成了一个循环链表。如下图:

JS中数据结构之链表的更多相关文章

  1. JS中数据结构之二叉查找树

    树是一种非线性的数据结构,以分层的方式存储数据.在二叉树上进行查找非常快,为二叉树添加或删除元素也非常快. 一棵树最上面的节点称为根节点,如果一个节点下面连接多个节点,那么该节点称为父节点,它下面的节 ...

  2. JS中数据结构之集合

    集合(set)是一种包含不同元素的数据结构.集合中的元素称为成员.集合的两个最重要特性是:首先,集合中的成员是无序的:其次,集合中不允许相同成员存在.当你想要创建一个数据结构用来保存一些独一无二的元素 ...

  3. JS中数据结构之散列表

    散列是一种常用的数据存储技术,散列后的数据可以快速地插入或取用.散列使用的数据 结构叫做散列表.在散列表上插入.删除和取用数据都非常快. 下面的散列表是基于数组进行设计的,数组的长度是预先设定的,如有 ...

  4. JS中数据结构之字典

    字典是一种以键 - 值对形式存储数据的数据结构 通过数组实现字典 function Dictionary() { this.add = add; this.datastore = new Array( ...

  5. JS中数据结构之栈

    1.栈的基本介绍 栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且容易实现. 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶.栈被称为一种后入先出( ...

  6. JS中数据结构之列表

    列表是一组有序的数据.每个列表中的数据项称为元素.在 JavaScript 中,列表中的元素可以是任意数据类型.列表中可以保存多少元素并没有事先限定并可以不断壮大,实际使用时元素的数量受到程序内存的限 ...

  7. JS中数据结构之图

    图由边的集合及顶点的集合组成.边是有方向的是有序图(有向图),否则就是无序图(无向图).图中的一系列顶点构成路径,路径中所有的顶点都由边连接.路径的长度用路径中第一个顶点到最后一个顶点之间边的数量表示 ...

  8. JS中数据结构之队列

    队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素.队列用于存储按 顺序排列的数据,先进先出. 队列的两种主要操作是:向队列中插入新元素和删除队列中的元素.插入操作也叫做入 队,删除操作也 ...

  9. JS高级-数据结构的封装

    最近在看了<数据结构与算法JavaScript描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质 ...

随机推荐

  1. tools-eclipse-003-下载安装优化

    一.下载 1.1.jdk安装 下载:http://www.oracle.com/technetwork/java/javase/downloads/index.html 安装:不需要安装jre,默认会 ...

  2. win2016

    slmgr /ipk CB7KF-BWN84-R7R2Y-793K2-8XDDG slmgr /skms kms.03k.org slmgr /ato

  3. Nginx+Tomcat实现单IP、多域名、多站点的访问

    最近帮朋友做了两个网站,预算很小很小.小到两个网站只能跑在一台512M内存的公网服务器上(tomcat+MySQL,由于内存太小了,只能把两个网站部署在同一个tomcat上),每个网站有自己的域名,初 ...

  4. mariadb(二)增删改

    一.表的结构的增删改 添加数据类型 alter table 表名 add 字段 数据类型: #如果字段存在则会报错 Duplicate column name '字段' #修改数据类型 alter t ...

  5. TCP 为什么是三次握手,而不是两次或四次?

    记得第一次看TCP握手连接的时候,有同样的疑问,我的疑问是,为何不是两次呢?后来随着对网络的理解深入,明白TCP报文是交由IP网络来负责运输,IP网络并不能保证TCP报文到达目的地,既然IP网络是指望 ...

  6. Normal Equation Algorithm求解多元线性回归的Octave仿真

    Normal Equation算法及其简洁,仅需一步即可计算出theta的取值,实现如下: function [theta] = normalEqn(X, y) theta = zeros(size( ...

  7. Ural Amount of Degrees(数位dp)

    传送门 Amount of Degrees Time limit: 1.0 secondMemory limit: 64 MB Description Create a code to determi ...

  8. 数据库学习之mysql数据库

    参考链接网站: http://c.biancheng.net/view/2361.html Mysql的版本以及版本号 MySQL Community Server(社区版):该版本完全免费,但是官方 ...

  9. .Net core 2.0 利用Attribute获取MVC Action来生成菜单

    最近在学习.net core的同时将老师的MVC5项目中的模块搬过来用,其中有一块就是利用Attribute来生成菜单. 一·首先定义Action实体 /// <summary> /// ...

  10. Java中的容器(集合)之HashMap源码解析

    1.HashMap源码解析(JDK8) 基础原理: 对比上一篇<Java中的容器(集合)之ArrayList源码解析>而言,本篇只解析HashMap常用的核心方法的源码. HashMap是 ...