Last active
March 4, 2020 12:01
-
-
Save Prottoy2938/0416b9d98d115fa7cea9258c617c71ce to your computer and use it in GitHub Desktop.
Doubly Linked List example in JavaScript with multiple common methods
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
//Doubly Linked List is almost similar to singlyLinkedList, except every node has another pointer to the previous node. | |
class Node { | |
constructor(val, prev = null, next = null) { | |
this.val = val; | |
this.prev = prev; | |
this.next = next; | |
} | |
} | |
class DoublyLinkedList { | |
constructor() { | |
this.head = null; | |
this.tail = null; | |
this.length = 0; | |
} | |
//pushes node to the end of the list | |
push(val) { | |
const newNode = new Node(val); | |
if (this.length === 0) { | |
this.head = newNode; | |
this.tail = newNode; | |
} else { | |
//`this.tail.next` has the same reference as `this.head`'s last item. So modifying `this.tail.next` will also modifies `this.head`'s last item. | |
this.tail.next = newNode; | |
newNode.prev = this.tail; | |
this.tail = newNode; | |
} | |
this.length++; | |
return this; | |
} | |
//removes first node from the end of the list | |
pop() { | |
if (!this.head) return null; | |
const poppedNode = this.tail; | |
if (this.length === 1) { | |
this.head = null; | |
this.tail = null; | |
} else { | |
this.tail = poppedNode.prev; | |
this.tail.next = null; | |
poppedNode.prev = null; | |
} | |
this.length--; | |
return poppedNode; | |
} | |
//removes node from the beginning of the list | |
shift() { | |
if (this.length === 0) return null; | |
const oldHead = this.head; | |
if (this.length === 1) { | |
this.head = null; | |
this.tail = null; | |
} else { | |
this.head = oldHead.next; | |
this.head.prev = null; | |
oldHead.next = null; | |
} | |
this.length--; | |
return oldHead; | |
} | |
//adds new node to the beginning of the list | |
unShift(val) { | |
const newNode = new Node(val); | |
if (this.length === 0) { | |
this.head = newNode; | |
this.tail = newNode; | |
} else { | |
this.head.prev = newNode; | |
newNode.next = this.head; | |
this.head = newNode; | |
} | |
this.length++; | |
return this; | |
} | |
//gets node based on index | |
get(index) { | |
if (index < 0 || index >= this.length) return null; | |
let count, current; | |
if (index <= this.length / 2) { | |
count = 0; | |
current = this.head; | |
while (count !== index) { | |
current = current.next; | |
count++; | |
} | |
} else { | |
count = this.length - 1; | |
current = this.tail; | |
while (count !== index) { | |
current = current.prev; | |
count--; | |
} | |
} | |
return current; | |
} | |
//modifies an existing node | |
set(index, val) { | |
let foundNode = this.get(index); | |
if (foundNode != null) { | |
foundNode.val = val; | |
return true; | |
} | |
return false; | |
} | |
//inserts a new node at given index | |
insert(idx, val) { | |
if (idx < 0 || idx > this.length) return false; | |
if (idx === 0) return !!this.unshift(val); | |
if (idx === this.length) return !!this.push(val); | |
const newNode = new Node(val); | |
const prevNode = this.get(idx - 1); | |
const nextNode = prevNode.next; | |
prevNode.next = newNode; | |
nextNode.prev = newNode; | |
newNode.next = nextNode; | |
newNode.prev = prevNode; | |
this.length++; | |
return true; | |
} | |
//removes a node | |
remove(idx) { | |
if (idx < 0 || idx >= this.length) return null; | |
if (idx === 0) return this.shift(); | |
if (idx === this.length - 1) return this.pop(); | |
const removedNode = this.get(idx); | |
const prevNode = removedNode.prev; | |
const nextNode = removedNode.next; | |
prevNode.next = nextNode; | |
nextNode.prev = prevNode; | |
//removing the connection | |
removedNode.prev = null; | |
removedNode.next = null; | |
this.length--; | |
return removedNode; | |
} | |
} | |
//EXAMPLES=========================================================================================== | |
const doublyLinkedList = new DoublyLinkedList(); | |
doublyLinkedList | |
.push("Hello") | |
.push("World") | |
.push("!") | |
.push("!"); | |
doublyLinkedList.pop(); | |
doublyLinkedList.shift(); | |
doublyLinkedList.unShift("Hello"); | |
doublyLinkedList.get(1); | |
doublyLinkedList.set(1, "Earth"); | |
doublyLinkedList.insert(2, "World"); | |
doublyLinkedList.remove(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment