forked from OpenGenus/cosmos
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request OpenGenus#3656 from steven-isbell/master
SLL, DLL, Trie in JS
- Loading branch information
Showing
2 changed files
with
258 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,191 @@ | ||
/* Part of Cosmos by OpenGenus Foundation */ | ||
|
||
// Singly Linked List | ||
class Node { | ||
constructor(data) { | ||
this.data = data; | ||
this.next = null; | ||
} | ||
} | ||
class LinkedList { | ||
constructor(value) { | ||
this.head = null; | ||
this.length = 0; | ||
this.addToHead(value); | ||
constructor() { | ||
this.head = null; | ||
this.length = 0; | ||
} | ||
|
||
add(data) { | ||
const nodeToAdd = new Node(data); | ||
let current = this.head; | ||
|
||
if (!current) { | ||
this.head = nodeToAdd; | ||
this.length++; | ||
return nodeToAdd; | ||
} | ||
|
||
while (current.next) { | ||
current = current.next; | ||
} | ||
|
||
current.next = nodeToAdd; | ||
this.length++; | ||
|
||
return nodeToAdd; | ||
} | ||
|
||
get(num) { | ||
if (num > this.length) return "Doesn't Exist!"; | ||
|
||
let current = this.head; | ||
let count = 1; | ||
|
||
while (count < num) { | ||
current = current.next; | ||
count++; | ||
} | ||
|
||
return current; | ||
} | ||
|
||
remove(num) { | ||
if (num > this.length) return "Doesn't Exist!"; | ||
|
||
let current = this.head; | ||
let count = 1; | ||
let prevNode = null; | ||
|
||
if (num === 1) { | ||
this.head = head.next; | ||
this.length--; | ||
|
||
return this.head; | ||
} | ||
|
||
addToHead(value) { | ||
const newNode = { value }; | ||
newNode.next = this.head; | ||
this.head = newNode; | ||
this.length++; | ||
return this; | ||
|
||
while (count < num) { | ||
prevNode = current; | ||
current = current.next; | ||
count++; | ||
} | ||
|
||
prevNode.next = current.next; | ||
this.length--; | ||
|
||
return this.head; | ||
} | ||
} | ||
|
||
// SLL Examples | ||
List.add('Luke'); | ||
List.add('Leia'); | ||
List.add('R2D2'); | ||
List.get(1); | ||
List.remove(2); | ||
|
||
// Doubly Linked List | ||
class Node { | ||
constructor(data) { | ||
this.data = data; | ||
this.previous = null; | ||
this.next = null; | ||
} | ||
} | ||
|
||
class DoublyLinkedList { | ||
constructor() { | ||
this.head = null; | ||
this.tail = null; | ||
this.length = 0; | ||
} | ||
add(data) { | ||
const node = new Node(data); | ||
if (!this.head) { | ||
this.head = node; | ||
this.tail = node; | ||
} else { | ||
node.previous = this.tail; | ||
this.tail.next = node; | ||
this.tail = node; | ||
} | ||
|
||
removeFromHead() { | ||
if (this.length === 0) { | ||
return undefined; | ||
this.length++; | ||
} | ||
remove(data) { | ||
let current = this.head; | ||
while (current) { | ||
if (current.data === data) { | ||
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.previous = null; | ||
} else if (current === this.tail) { | ||
this.tail = this.tail.previous; | ||
this.tail.next = null; | ||
} else { | ||
current.previous.next = current.next; | ||
current.next.previous = current.previous; | ||
} | ||
|
||
const value = this.head.value; | ||
this.head = this.head.next; | ||
this.length--; | ||
return value; | ||
} | ||
current = current.next; | ||
} | ||
|
||
find(val) { | ||
let thisNode = this.head; | ||
|
||
while(thisNode) { | ||
if(thisNode.value === val) { | ||
return thisNode; | ||
} | ||
|
||
thisNode = thisNode.next; | ||
} | ||
insertAfter(data, toNodeData) { | ||
let current = this.head; | ||
while (current) { | ||
if (current.data === toNodeData) { | ||
const node = new Node(data); | ||
if (current === this.tail) { | ||
this.add(data); | ||
} else { | ||
current.next.previous = node; | ||
node.previous = current; | ||
node.next = current.next; | ||
current.next = node; | ||
this.length++; | ||
} | ||
return thisNode; | ||
} | ||
current = current.next; | ||
} | ||
|
||
remove(val) { | ||
if(this.length === 0) { | ||
return undefined; | ||
} | ||
|
||
if (this.head.value === val) { | ||
return this.removeFromHead(); | ||
} | ||
|
||
let previousNode = this.head; | ||
let thisNode = previousNode.next; | ||
|
||
while(thisNode) { | ||
if(thisNode.value === val) { | ||
break; | ||
} | ||
|
||
previousNode = thisNode; | ||
thisNode = thisNode.next; | ||
} | ||
|
||
if (thisNode === null) { | ||
return undefined; | ||
} | ||
|
||
previousNode.next = thisNode.next; | ||
this.length--; | ||
return this; | ||
} | ||
traverse(fn) { | ||
let current = this.head; | ||
while (current) { | ||
if (fn) { | ||
fn(current); | ||
} | ||
current = current.next; | ||
} | ||
} | ||
traverseReverse(fn) { | ||
let current = this.tail; | ||
while (current) { | ||
if (fn) { | ||
fn(current); | ||
} | ||
current = current.previous; | ||
} | ||
} | ||
length() { | ||
return this.length; | ||
} | ||
print() { | ||
let string = ''; | ||
let current = this.head; | ||
while (current) { | ||
string += current.data + ' '; | ||
current = current.next; | ||
} | ||
console.log(string.trim()); | ||
} | ||
} | ||
|
||
// DLL Examples | ||
const doublyLinkedList = new DoublyLinkedList(); | ||
|
||
doublyLinkedList.print(); | ||
doublyLinkedList.add(1); | ||
doublyLinkedList.add(2); | ||
doublyLinkedList.add(3); | ||
doublyLinkedList.add(4); | ||
doublyLinkedList.print(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* Part of Cosmos by OpenGenus Foundation */ | ||
|
||
class Node { | ||
constructor() { | ||
this.keys = new Map(); | ||
this.end = false; | ||
} | ||
setEnd() { | ||
this.end = true; | ||
} | ||
isEnd() { | ||
return this.end; | ||
} | ||
} | ||
|
||
class Trie { | ||
constructor() { | ||
this.root = new Node(); | ||
} | ||
|
||
add(input, node = this.root) { | ||
if (input.length === 0) { | ||
node.setEnd(); | ||
return; | ||
} else if (!node.keys.has(input[0])) { | ||
node.keys.set(input[0], new Node()); | ||
return this.add(input.substr(1), node.keys.get(input[0])); | ||
} else { | ||
return this.add(input.substr(1), node.keys.get(input[0])); | ||
} | ||
} | ||
isWord(word) { | ||
let node = this.root; | ||
while (word.length > 1) { | ||
if (!node.keys.has(word[0])) { | ||
return false; | ||
} else { | ||
node = node.keys.get(word[0]); | ||
word = word.substr(1); | ||
} | ||
} | ||
return node.keys.has(word) && node.keys.get(word).isEnd() ? true : false; | ||
} | ||
print() { | ||
let words = []; | ||
const search = function(node, string) { | ||
if (node.keys.size !== 0) { | ||
for (let letter of node.keys.keys()) { | ||
search(node.keys.get(letter), string.concat(letter)); | ||
} | ||
if (node.isEnd()) { | ||
words.push(string); | ||
} | ||
} else { | ||
string.length > 0 ? words.push(string) : undefined; | ||
return; | ||
} | ||
}; | ||
search(this.root, ''); | ||
return words.length > 0 ? words : mo; | ||
} | ||
} | ||
|
||
// Trie Examples | ||
|
||
myTrie.add('cat'); | ||
myTrie.add('catch'); | ||
myTrie.add('dog'); | ||
myTrie.add('good'); | ||
myTrie.add('goof'); | ||
myTrie.add('jest'); | ||
myTrie.add('come'); | ||
myTrie.add('comedy'); | ||
myTrie.isWord('catc'); | ||
myTrie.isWord('jest'); | ||
myTrie.isWord('come'); | ||
myTrie.print(); |