A linked list is a collection of items where each item points to the next one in the list. Because of this structure, linked lists are very slow when searching for an item at a particular index. An array, by comparison, has quick gets when searching for an index, but a linked list must start at the beginning, often called the "head", and loop through each item's next property until we arrive at the item. This makes gets in a linked list an operation that takes O(n) time.

While gets might be slow in a linked list, it's other operations, like push and delete come with some great benefits we will see in the lesson.

  1. /**
  2. * Linked list
  3. *
  4. * API:
  5. * push
  6. * pop
  7. * get
  8. * delete
  9. * isEmpty
  10. * print
  11. */
  12.  
  13. function createNode(value) {
  14. return {
  15. value,
  16. next: null
  17. }
  18. }
  19.  
  20. function createLinkedList() {
  21. return {
  22. head: null,
  23. tail: null,
  24. length: 0,
  25. push(value) {
  26. /**Key takeaway:
  27. * Assign new node to current tail's next value
  28. * Then
  29. * Reassign the tail to new node
  30. */
  31. // Create Node
  32. const node = createNode(value);
  33.  
  34. // If this is the first one
  35. if (this.head === null) {
  36. this.head = node
  37. this.tail = node
  38. this.length++;
  39. return node;
  40. }
  41.  
  42. // if there already has nodes
  43. this.tail.next = node;
  44. this.tail = node;
  45. this.length++;
  46. return node;
  47. },
  48. pop() {
  49. const node = this.tail;
  50. // if this is no node
  51. if (!this.head) {
  52. return null;
  53. }
  54.  
  55. // if there is one node
  56. if (this.head === this.tail) {
  57. this.head = null;
  58. this.tail = null;
  59. return node;
  60. }
  61.  
  62. let current = this.head;
  63. let penultimate = null;
  64.  
  65. while (current) {
  66. const {next} = current;
  67. if (next && next == this.tail) {
  68. penultimate = current;
  69. break;
  70. }
  71. current = current.next;
  72. }
  73. penultimate.next = null;
  74. this.tail = penultimate;
  75. this.length--;
  76. return node;
  77. },
  78. get(index = 0) {
  79. // no node in the list, return null
  80. if (!this.head) {
  81. return null;
  82. }
  83.  
  84. // if the index < 0 or > length - 1, out of range
  85. if (index < 0 || index > this.length - 1) {
  86. return null;
  87. }
  88.  
  89. // if index = 0, then return the first
  90. if (index === 0) {
  91. return this.head;
  92. }
  93.  
  94. let current = this.head;
  95. let i = 0;
  96. while (i < index) {
  97. i++;
  98. current = current.next;
  99. }
  100.  
  101. return current;
  102. },
  103. delete(index = 0) {
  104. /**
  105. * Key takewawy:
  106. * If we delete tail, we need to reassign the tail
  107. */
  108. // no node in the list, return null
  109. if (!this.head) {
  110. return null;
  111. }
  112.  
  113. // if the index < 0 or > length - 1, out of range
  114. if (index < 0 || index > this.length - 1) {
  115. return null;
  116. }
  117.  
  118. // if index = 0, then return the first
  119. if (index === 0) {
  120. const node = this.head;
  121. this.head = node.next;
  122. this.length--;
  123. return node;
  124. }
  125.  
  126. let i = 0;
  127. let current = this.head;
  128. let previous = null;
  129.  
  130. while (i < index) {
  131. i++;
  132. previous = current;
  133. current = current.next;
  134. }
  135.  
  136. const deleted = current;
  137. previous.next = deleted.next;
  138.  
  139. // If we delete the tail, we need to reassign tail
  140. if (previous.next === null) {
  141. this.tail = previous;
  142. }
  143.  
  144. this.length--;
  145. return deleted;
  146. },
  147. isEmpty() {
  148. return this.length === 0;
  149. },
  150. print() {
  151. /**Key takeway:
  152. * remember to assign next node to current
  153. * Move the while loop
  154. * */
  155. let nodes = [];
  156.  
  157. if (!this.head) {
  158. return 'Empty list';
  159. }
  160.  
  161. let current = this.head;
  162. while (current) {
  163. nodes.push(current.value);
  164. current = current.next;
  165. }
  166.  
  167. return nodes.join(' => ');
  168. }
  169. };
  170. }
  171.  
  172. module.exports = {createLinkedList}

test:

  1. const {createLinkedList} = require('../src/linked-list');
  2.  
  3. describe('linked list', () => {
  4. test('push: should add node into array', () => {
  5. const l = createLinkedList();
  6. // linked list should be empty
  7. expect(l.isEmpty()).toBe(true);
  8. // push a new node
  9. l.push('a');
  10. expect(l.isEmpty()).toBe(false);
  11. expect(l.length).toEqual(1);
  12. expect(l.print()).toEqual('a');
  13. // push a second node
  14. l.push('b');
  15. expect(l.length).toEqual(2);
  16. expect(l.print()).toEqual('a => b');
  17. });
  18.  
  19. test('pop: should remove the last node from the list', () => {
  20. const l = createLinkedList();
  21. l.push('a');
  22. l.push('b');
  23. l.push('c');
  24. expect(l.length).toEqual(3);
  25. const p = l.pop();
  26. expect(p.value).toEqual('c');
  27. expect(l.length).toEqual(2);
  28. });
  29.  
  30. test('get: should return the node for the given index', () => {
  31. const l = createLinkedList();
  32. // empty list, return null
  33. expect(l.get(0)).toBeNull();
  34. l.push('a');
  35. l.push('b');
  36. l.push('c');
  37. expect(l.length).toEqual(3);
  38. // out of index, retur null
  39. expect(l.get(-1)).toBeNull();
  40. expect(l.get(4)).toBeNull();
  41.  
  42. // return the head
  43. expect(l.get(0).value).toEqual('a');
  44.  
  45. // index in range not head
  46. expect(l.get(2).value).toEqual('c');
  47. });
  48.  
  49. test('delete: should delete the node from the given index', () => {
  50. const l = createLinkedList();
  51. // empty list, return null
  52. expect(l.delete(0)).toBeNull();
  53. l.push('a');
  54. l.push('b');
  55. l.push('c');
  56. expect(l.length).toEqual(3);
  57. // out of index, retur null
  58. expect(l.delete(-1)).toBeNull();
  59. expect(l.delete(4)).toBeNull();
  60. // return the head
  61. expect(l.delete(0).value).toEqual('a');
  62. expect(l.length).toEqual(2);
  63. // delete the tail, reassign the tail
  64. expect(l.delete(1).value).toEqual('c');
  65. expect(l.tail.value).toEqual('b');
  66. });
  67. });

[Algorithm] Linked List Data Structure in JavaScript的更多相关文章

  1. [Algorithms] Tree Data Structure in JavaScript

    In a tree, nodes have a single parent node and may have many children nodes. They never have more th ...

  2. [Algorithom] Stack Data Structure in JavaScript

    A stack is a collection of items that obeys the principle of "last in, first out". Like a ...

  3. [Algorithm] JavaScript Graph Data Structure

    A graph is a data structure comprised of a set of nodes, also known as vertices, and a set of edges. ...

  4. [Algorithm] Heap data structure and heap sort algorithm

    Source, git Heap is a data structure that can fundamentally change the performance of fairly common ...

  5. [Algorithm] Trie data structure

    For example we have an array of words: [car, done, try, cat, trie, do] What is the best data structu ...

  6. HDU5739 Fantasia(点双连通分量 + Block Forest Data Structure)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5739 Description Professor Zhang has an undirect ...

  7. hdu-5929 Basic Data Structure(双端队列+模拟)

    题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  8. CDOJ 483 Data Structure Problem DFS

    Data Structure Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/proble ...

  9. HDU 5929 Basic Data Structure 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

    Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

随机推荐

  1. 理一理Spring如何对接JUnit

    测试代码 package org.simonme.srcstudy.spring3.demo.stub; import static org.junit.Assert.assertNotNull; i ...

  2. Selenium WebDriver-通过ActionChains实现页面元素拖拽

    #encoding=utf-8 import unittest import time import chardet from selenium import webdriver class Visi ...

  3. 2章 perl标量变量

    标量变量 单单存储一个值得变量   ,单个标量值 $name   为变量  区分大小写 $barney=$barney*2   第一次  取值  等号右边    :第二次  赋值 等号左边 双目操作符 ...

  4. 《如何成为一位大家愿意追随的Leader》读后感

    今天看了左耳朵耗子老师的文章<如何成为一位大家愿意追随的Leader>深有感触.每一行字都往心里说,文章里说到Leader和Boss的不同点在于,Leader是大家跟我一起上,而Boss则 ...

  5. FZOJ Problem 2107 Hua Rong Dao

                                                                                                        ...

  6. SharepPoint 2013安装体会

    SharePoint 2013出来了,一直没有找到合适的机器来安装.前天腾出来一台内存8G的机器,决定在Hyper-V上安装在一台虚机,然后装个Windows 2012,再装SharePoint 20 ...

  7. POJ3928 Ping pong

      Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu Description N(3<= ...

  8. net4:GridView中的重要操作(添加checkbox,以及鼠标动作,行颜色等)

    原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  9. 转 Python常见数据结构整理

    http://www.cnblogs.com/jeffwongishandsome/archive/2012/08/05/2623660.html Python常见数据结构整理 Python中常见的数 ...

  10. upper_bound()和lower_bound()

    ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, la ...