From 8c796fcf479dd9bd17eada806208de98fd505f2f Mon Sep 17 00:00:00 2001 From: xarielx Date: Fri, 18 Oct 2019 16:47:16 -0400 Subject: [PATCH] Added Doubly Linked List DS example --- .gitignore | 1 + package-lock.json | 64 +++++++ package.json | 2 + src/dataStructures/doublyLinkedList.js | 245 +++++++++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 .gitignore create mode 100644 src/dataStructures/doublyLinkedList.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package-lock.json b/package-lock.json index 15495a9..602e426 100644 --- a/package-lock.json +++ b/package-lock.json @@ -873,6 +873,54 @@ "restore-cursor": "^2.0.0" } }, + "cli-table2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", + "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", + "requires": { + "colors": "^1.1.2", + "lodash": "^3.10.1", + "string-width": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -894,6 +942,11 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -916,6 +969,12 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "optional": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3514,6 +3573,11 @@ "path-key": "^2.0.0" } }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, "nwsapi": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", diff --git a/package.json b/package.json index c2c6cdc..5e92798 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ }, "homepage": "https://github.com/nas5w/javascript-patterns#readme", "dependencies": { + "chalk": "^2.4.2", + "cli-table2": "^0.2.0", "husky": "^1.3.1", "jest": "^24.7.1" }, diff --git a/src/dataStructures/doublyLinkedList.js b/src/dataStructures/doublyLinkedList.js new file mode 100644 index 0000000..1309b0f --- /dev/null +++ b/src/dataStructures/doublyLinkedList.js @@ -0,0 +1,245 @@ +const Table = require('cli-table2'); +const chalk = require('chalk'); + +class Node { + constructor(data) { + this.data = data; + this.next = null; + this.prev = null; + } +} + +class DoublyLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + + append(item) { + let node = new Node(item); + + if (!this.head) { + this.head = node; + this.tail = node; + } else { + node.prev = this.tail; + this.tail.next = node; + this.tail = node + } + } + + appendAt(pos, item) { + let current = this.head; + let counter = 1; + let node = new Node(item); + if (pos == 0) { + this.head.prev = node + node.next = this.head + this.head = node + } else { + while (current) { + current = current.next; + if (counter == pos) { + node.prev = current.prev + current.prev.next = node + node.next = current + current.prev = node + } + counter++ + } + } + } + + appendAfter(item) { + // + } + + remove(item) { + let current = this.head; + while (current) { + if (current.data === item) { + if (current == this.head && current == this.tail) { + this.head = null; + this.tail = null; + } else if (current == this.head) { + this.head = this.head.next + this.head.prev = null + } else if (current == this.tail) { + this.tail = this.tail.prev; + this.tail.next = null; + } else { + current.prev.next = current.next; + current.next.prev = current.prev; + } + } + current = current.next + } + } + + removeAt(pos) { + let current = this.head; + let counter = 1; + if (pos == 0) { + this.head = this.head.next; + this.head.prev = null; + } else { + while (current) { + current = current.next + if (current == this.tail) { + this.tail = this.tail.prev; + this.tail.next = null; + } else if (counter == pos) { + current.prev.next = current.next; + current.next.prev = current.prev; + break; + } + counter++; + } + } + } + + reverse() { + let current = this.head; + let prev = null; + while (current) { + let next = current.next + current.next = prev + current.prev = next + prev = current + current = next + } + this.tail = this.head + this.head = prev + } + + swap(nodeOne, nodeTwo) { + let current = this.head; + let counter = 0; + let firstNode; + + // Make sure we are okay to go + if (nodeOne === nodeTwo) { + console.log("ERROR: 'SWAP' both the nodes must be different!"); + return false; + } else if (nodeOne > nodeTwo) { + let temp = nodeOne; + nodeOne = nodeTwo; + nodeTwo = temp; + } + + if (nodeOne < 0 || nodeTwo < 0) { + console.log("ERROR: 'SWAP' both the nodes must be index & index can not be negative!"); + return false; + } + + // Swap nodes + while (current !== null) { + if (counter == nodeOne) { + firstNode = current; + } else if (counter == nodeTwo) { + let temp = current.data; + current.data = firstNode.data; + firstNode.data = temp; + } + current = current.next; + counter++; + } + return true + } + + length() { + let current = this.head; + let counter = 0; + while (current !== null) { + counter++ + current = current.next + } + return counter; + } + + display() { + let current = this.head; + let elements = []; + while (current !== null) { + elements.push(current.data); + current = current.next + } + return elements.join(" "); + } + + isEmpty() { + return this.length() < 1 + } + + traverse(fn) { + if (!fn || typeof fn !== 'function') { + console.log("ERROR: 'TRAVERSE' function is undefined!"); + return false; + } + let current = this.head; + while (current !== null) { + fn(current) + current = current.next; + } + return true; + } + + traverseReverse(fn) { + if (!fn || typeof fn !== 'function') { + console.log("ERROR: 'TRAVERSE_REVERSE' function is undefined!"); + return false; + } + let current = this.tail; + while (current !== null) { + fn(current) + current = current.prev; + } + return true; + } + + search(item) { + let current = this.head; + let counter = 0; + + while (current) { + if (current.data == item) { + return counter + } + current = current.next + counter++ + } + return false; + } + + /* + * EXTRA + */ + prettyPrint() { + let current = this.head; + let output = [chalk.red('Head') + ' ->']; + while (current !== null) { + output.push(chalk.cyan(current.data)); + current = current.next; + } + output.push('<- ' + chalk.red('Tail')); + this.table(output); + return true; + } // + + table(output) { + let table = new Table({ + chars: { + 'top': '─', 'top-mid': '╤', 'top-left': '╔', 'top-right': '╗' + , 'bottom': '─', 'bottom-mid': '╧', 'bottom-left': '╚', 'bottom-right': '╝' + , 'left': '│', 'left-mid': '╟', 'mid': '─', 'mid-mid': '┼' + , 'right': '│', 'right-mid': '╢', 'middle': '│' + }, + style: { border: ['yellow'] } + }); + table.push(output); + console.log(table.toString()); + return true + } // +} + +module.exports = DoublyLinkedList \ No newline at end of file