Skip to content

Instantly share code, notes, and snippets.

@Prottoy2938
Last active March 4, 2020 12:01
Show Gist options
  • Save Prottoy2938/0416b9d98d115fa7cea9258c617c71ce to your computer and use it in GitHub Desktop.
Save Prottoy2938/0416b9d98d115fa7cea9258c617c71ce to your computer and use it in GitHub Desktop.
Doubly Linked List example in JavaScript with multiple common methods
//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