DoublyLinkedList.js
 1  "use strict";
 2  
 3  Object.defineProperty(exports, "__esModule", {
 4      value: true
 5  });
 6  // Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
 7  // used for queues. This implementation assumes that the node provided by the user can be modified
 8  // to adjust the next and last properties. We implement only the minimal functionality
 9  // for queue support.
10  class DLL {
11      constructor() {
12          this.head = this.tail = null;
13          this.length = 0;
14      }
15  
16      removeLink(node) {
17          if (node.prev) node.prev.next = node.next;else this.head = node.next;
18          if (node.next) node.next.prev = node.prev;else this.tail = node.prev;
19  
20          node.prev = node.next = null;
21          this.length -= 1;
22          return node;
23      }
24  
25      empty() {
26          while (this.head) this.shift();
27          return this;
28      }
29  
30      insertAfter(node, newNode) {
31          newNode.prev = node;
32          newNode.next = node.next;
33          if (node.next) node.next.prev = newNode;else this.tail = newNode;
34          node.next = newNode;
35          this.length += 1;
36      }
37  
38      insertBefore(node, newNode) {
39          newNode.prev = node.prev;
40          newNode.next = node;
41          if (node.prev) node.prev.next = newNode;else this.head = newNode;
42          node.prev = newNode;
43          this.length += 1;
44      }
45  
46      unshift(node) {
47          if (this.head) this.insertBefore(this.head, node);else setInitial(this, node);
48      }
49  
50      push(node) {
51          if (this.tail) this.insertAfter(this.tail, node);else setInitial(this, node);
52      }
53  
54      shift() {
55          return this.head && this.removeLink(this.head);
56      }
57  
58      pop() {
59          return this.tail && this.removeLink(this.tail);
60      }
61  
62      toArray() {
63          return [...this];
64      }
65  
66      *[Symbol.iterator]() {
67          var cur = this.head;
68          while (cur) {
69              yield cur.data;
70              cur = cur.next;
71          }
72      }
73  
74      remove(testFn) {
75          var curr = this.head;
76          while (curr) {
77              var { next } = curr;
78              if (testFn(curr)) {
79                  this.removeLink(curr);
80              }
81              curr = next;
82          }
83          return this;
84      }
85  }
86  
87  exports.default = DLL;
88  function setInitial(dll, node) {
89      dll.length = 1;
90      dll.head = dll.tail = node;
91  }
92  module.exports = exports["default"];