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!
Tasks
- Have a look at the
get
method in the Singly Linked List. What are the differences between the Doubly Linked List and the Singly Linked List? Are there some Pros and Cons?
Top comments (0)