Hi ?, welcome back. It's been exactly 6 days since we started this journey together. I want to believe it has been an awesome experience. Yesterday, we learned about Singly Linked Lists, how to implement them in JavaScript with a few basic operations. Today, we'll learn how to implement Doubly Linked Lists in JavaScript. So, let's dive in! ?♂️
When it comes to data structures, the Doubly Linked List is a versatile and powerful tool. ?️ It's a type of linked list where each node contains a data field and two pointers, one pointing to the next node and the other pointing to the previous node. This bidirectional traversal capability makes doubly linked lists particularly useful in various programming scenarios like:
A doubly-linked list is like a singly-linked list, but with an extra feature: you can move in both directions. This means you can go from the start to the end of the list. In the next section, we'll learn how to implement a doubly-linked list in JavaScript. ?
By the way, if you missed the previous article on singly-linked lists, you can check it out here.
As we already know from last article, we'll need to create a Node class to represent each element in the list. This is similar to what we did in the previous article except that we'll need to add a prev property to the Node class to keep track of the previous node (which is the exact feature that makes a doubly-linked list different from a singly-linked list).
class Node { constructor(data) { this.data = data; this.prev = null; this.next = null; } }
This is a simple visualization of what we've just created.
Now that we have our Node class, let's implement the DoublyLinkedList class.
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Methods will be implemented here ? }
Now that we have our DoublyLinkedList class, let's start implementing our methods.
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } insertAtBeginning(data) { const newNode = new Node(data); if (!this.head) { this.head = newNode; this.tail = newNode; } else { newNode.next = this.head; this.head.prev = newNode; this.head = newNode; } this.length ; } // Other methods will be implemented here ? }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Insert at the end insertAtEnd(data) { const newNode = new Node(data); if (!this.tail) { this.head = newNode; this.tail = newNode; } else { newNode.prev = this.tail; this.tail.next = newNode; this.tail = newNode; } this.length ; } // Other methods will be implemented here ? }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Insert at a specific position insertAtPosition(data, position) { if (position this.length) { return false; // Invalid position } if (position === 0) { this.insertAtBeginning(data); return true; } if (position === this.length) { this.insertAtEnd(data); return true; } const newNode = new Node(data); let current = this.head; for (let i = 0; i
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Delete a node deleteNode(data) { if (!this.head) return false; let current = this.head; while (current) { if (current.data === data) { if (current === this.head && current === this.tail) { this.head = null; this.tail = null; } else if (current === this.head) { this.head = current.next; this.head.prev = null; } else if (current === this.tail) { this.tail = current.prev; this.tail.next = null; } else { current.prev.next = current.next; current.next.prev = current.prev; } this.length--; return true; } current = current.next; } return false; // Node not found } // Other methods will be implemented here ? }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Traverse forward traverseForward() { let current = this.head; while (current) { console.log(current.data); current = current.next; } } // Other methods will be implemented here ? }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Traverse backward traverseBackward() { let current = this.tail; while (current) { console.log(current.data); current = current.prev; } } }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } // Previous methods here ? // . // . // . // Search for a node search(data) { let current = this.head; let index = 0; while (current) { if (current.data === data) { return index; } current = current.next; index ; } return -1; // Node not found } // Other methods will be implemented here ? }
Here's a simple example of how to use our Doubly Linked List:
const list = new DoublyLinkedList();
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.insertAtBeginning(0);
list.insertAtPosition(1.5, 2);console.log("Forward traversal:");
list.traverseForward();console.log("Backward traversal:");
list.traverseBackward();console.log("Search for 2:", list.search(2));
list.deleteNode(1.5);
console.log("After deletion:");
list.traverseForward();
In this article, we've learned about the basics operations of doubly linked lists and how to implement
them in JavaScript. In the next article, we'll be learning about Circular Linked Lists, then we can solve some leetcode problems to deepen our understanding.
To ensure you don't miss any part of this series and to connect with me for more in-depth
discussions on Software Development (Web, Server, Mobile or Scraping / Automation), data
structures and algorithms, and other exciting tech topics, follow me on:
Stay tuned and happy coding ???
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3