DoublyLinkedList
A doubly linked list is just a linked list with additional pointer.
// Linked List with prev pointers
class Node {
constructor(value) {
this.value = value;
this.next = null;
this.prev = null;
}
}
class DoublyLinkedList {
constructor(value) {
this.head = new Node(value);
this.tail = this.head;
this.length = 1;
}
push(value) {
const newNode = new Node(value);
if (this.length === 0) {
this.head = this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail
this.tail = newNode
}
this.length++;
return this;
}
pop() {
if (!this.length)
return undefined;
if (this.length === 1) {
this.head = 1
this.tail = 1
}
const temp = this.tail;
this.tail = this.tail.prev;
temp.prev = null;
this.tail.next = null;
this.length--;
return temp;
}
unshift(value) {
if (!this.length)
return this.push(value)
else {
const newNode = new Node(value);
this.head.prev = newNode
newNode.next = this.head;
this.head = newNode
}
this.length++;
return this;
}
shift() {
if (!this.length)
return undefined;
const temp = this.head;
if (this.length === 1) {
this.head = this.tail = null;
} else {
this.head = this.head.next;
this.head.prev = null;
temp.next = null;
}
this.length--;
return temp
}
//we are using more efficient get than single linked list due to pointer fwd and back
//we can make use of prev pointer to divide into half and traverse backword
get(index) {
if (this.length === 0)
return undefined;
let temp;
if (index < this.length / 2) {
temp = this.head;
for (let i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = this.tail;
for (let i = this.length; i > index; i--) {
temp = temp.prev;
}
}
return temp
}
//set method is exactly same as DoublyLinkedList
//it calls get which is more effcient in get
set(value, index) {
if (index < 0 || index > this.length)
return undefined;
let temp = this.get(index);
if (temp) {
temp.value = value
return true
}
return false
}
insert(index, value) {
//insert from rightmost
if (index === this.length) {
return this.push(value);
}
//insert from leftmost
if (index === 0) {
return this.unshift(value);
}
if (index < 0 || index > this.length)
return undefined;
//insert at given index
const prev = this.get(index - 1);
const curr = prev.next;
const newNode = new Node(value);
prev.next = newNode;
newNode.prev = prev;
newNode.next = curr;
curr.prev = newNode;
this.length++;
return true
}
remove(index) {
if (index === 0)
return this.shift(value);
if (index === this.length)
return this.pop(value);
const toRemove = this.get(index);
toRemove.prev.next = toRemove.next;
toRemove.next.prev = toRemove.prev;
toRemove.next = toRemove.prev = null;
this.length--;
return toRemove;
}
}
const a = new DoublyLinkedList(1);
a.push(2)
a.push(3)
a.push(4)
a.push(5)
a.pop()
a.unshift(101)
console.log(a);