Intro
Last time, we learned how to shift / remove data from the beginning of our Doubly Linked List.
Today, we'll learn how to get a specific node by its index.
Starter Code
We start with code that has the push
method, because to remove data, we first have to add data.
class Node {
constructor(value) {
this.value = value;
this.prev = null;
this.next = null;
}
}
class DoublyLinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
push(value) {
const newNode = new Node(value);
if (!this.length) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.length += 1;
return newNode;
}
}
Thoughts
First, we should think about the constraints and possibilities:
If the list is empty, if the index is less than 0, or if the index is greater than or equal to the list length:
- return null
If the desired node is in the bottom half of the list:
- add counter
- start from the head
- go to the next node until we found our desired node
- return node
If the desired node is in the top half of the list:
- add counter
- start from the tail
- go to the previous node until we found our desired node
- return node
Example:
// current list:
A (head) <===> B <===> C (tail)
// desired node:
get(0); // A (starting from head)
get(1); // B (starting node doesn't matter, equal distance from head or tail)
get(2); // C (starting from tail)
Implementation (Short)
class Node {
constructor(value) {
this.value = value;
this.prev = null;
this.next = null;
}
}
class DoublyLinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
push(value) {
const newNode = new Node(value);
if (!this.length) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.length += 1;
return newNode;
}
get(index) {
// if list is empty, if index is less than 0, or if index is greater than or equal to the list length, return null
if (!this.length || index < 0 || index >= this.length) {
return null;
} else {
let currentNode;
// if the desired node is in the bottom half of the list
if (index < this.length / 2) {
// add counter, starting from 0 and counting upwards in the loop
let counter = 0;
// start from the head
currentNode = this.head;
// go to the next node until we found our desired node
while (counter < index) {
currentNode = currentNode.next;
counter += 1;
}
} else {
// add counter, starting from the top and counting downwards in the loop
let counter = this.length - 1;
// start from the tail
currentNode = this.tail;
// go to the previous node until we found our desired node
while (counter > index) {
currentNode = currentNode.prev;
counter -= 1;
}
}
// return node
return currentNode;
}
}
}
Result
Let's have a look how to use the Doubly Linked List's get
method and its results.
const newDLL = new DoublyLinkedList();
newDLL.push("A");
newDLL.push("B");
newDLL.push("C");
// nothing to see
console.log(newDLL.get(-1));
// null
// should be A
console.log(newDLL.get(0));
// <ref *1> Node {
// value: 'A',
// prev: null,
// next: <ref *2> Node {
// value: 'B',
// prev: [Circular *1],
// next: Node { value: 'C', prev: [Circular *2], next: null }
// }
// }
// should be B
console.log(newDLL.get(1));
// <ref *1> Node {
// value: 'B',
// prev: Node { value: 'A', prev: null, next: [Circular *1] },
// next: Node { value: 'C', prev: [Circular *1], next: null }
// }
// should be C
console.log(newDLL.get(2));
// <ref *2> Node {
// value: 'C',
// prev: <ref *1> Node {
// value: 'B',
// prev: Node { value: 'A', prev: null, next: [Circular *1] },
// next: [Circular *2]
// },
// next: null
// }
// nothing to see
console.log(newDLL.get(3));
// null
Next Part
We will implement our next method for the Doubly Linked List: set
/ update a specific node.
If you want to get notified, subscribe!