In this article, we will learn how to implement a LinkedList in JavaScript.
The Linked List Data Structure Overview
Linked lists store a sequential collection of elements; but unlike arrays, in linked lists, the elements are not placed contiguously in memory. Each element consists of a node that stores the element itself and also a reference (also known as a pointer or link) that points to the next element. The following diagram exemplifies the structure of a linked list:
Linked List Implementation Using JavaScript
Let's first create a Node class:
class Node {
constructor(element, next) {
this.element = element;
this.next = next;
}
}
Now, let's create a Linked List implementation in JavaScript:
class LinkedList {
constructor(equalsFn = defaultEquals) {
this.equalsFn = equalsFn;
this.count = 0;
this.head = undefined;
}
push(element) {
const node = new Node(element);
let current;
if (this.head == null) {
// catches null && undefined
this.head = node;
} else {
current = this.head;
while (current.next != null) {
current = current.next;
}
current.next = node;
}
this.count++;
}
getElementAt(index) {
if (index >= 0 && index <= this.count) {
let node = this.head;
for (let i = 0; i < index && node != null; i++) {
node = node.next;
}
return node;
}
return undefined;
}
insert(element, index) {
if (index >= 0 && index <= this.count) {
const node = new Node(element);
if (index === 0) {
const current = this.head;
node.next = current;
this.head = node;
} else {
const previous = this.getElementAt(index - 1);
node.next = previous.next;
previous.next = node;
}
this.count++;
return true;
}
return false;
}
removeAt(index) {
if (index >= 0 && index < this.count) {
let current = this.head;
if (index === 0) {
this.head = current.next;
} else {
const previous = this.getElementAt(index - 1);
current = previous.next;
previous.next = current.next;
}
this.count--;
return current.element;
}
return undefined;
}
remove(element) {
const index = this.indexOf(element);
return this.removeAt(index);
}
indexOf(element) {
let current = this.head;
for (let i = 0; i < this.size() && current != null; i++) {
if (this.equalsFn(element, current.element)) {
return i;
}
current = current.next;
}
return -1;
}
isEmpty() {
return this.size() === 0;
}
size() {
return this.count;
}
getHead() {
return this.head;
}
clear() {
this.head = undefined;
this.count = 0;
}
toString() {
if (this.head == null) {
return '';
}
let objString = `${this.head.element}`;
let current = this.head.next;
for (let i = 1; i < this.size() && current != null; i++) {
objString = `${objString},${current.element}`;
current = current.next;
}
return objString;
}
}
function defaultEquals(a, b) {
return a === b;
}
Using the Linked List
const list = new LinkedList();
console.log('push element 15');
list.push(15);
console.log('list.indexOf(15) => ', list.indexOf(15));
console.log('push element 10');
list.push(10);
console.log('list.toString() => ', list.toString());
console.log('list.indexOf(10) => ', list.indexOf(10));
console.log('push element 13');
list.push(13);
console.log('list.toString() => ', list.toString());
console.log('list.indexOf(13) => ', list.indexOf(13));
console.log('list.indexOf(10) => ', list.indexOf(10));
console.log('push elements 11 and 12');
list.push(11);
list.push(12);
console.log('list.toString() => ', list.toString());
console.log('list.removeAt(1) => ', list.removeAt(1));
console.log('list.toString() => ', list.toString());
console.log('list.removeAt(3) => ', list.removeAt(3));
console.log('list.toString() => ', list.toString());
console.log('push element 14');
list.push(14);
console.log('list.toString() => ', list.toString());
console.log('insert element 16 pos 0 => ', list.insert(16, 0));
console.log('list.toString() => ', list.toString());
console.log('insert element 17 pos 1 => ', list.insert(17, 1));
console.log('list.toString() => ', list.toString());
console.log('insert element 18 pos list.size() => ', list.insert(18, list.size()));
console.log('list.toString() => ', list.toString());
console.log('remove element 16 => ', list.remove(16));
console.log('list.toString() => ', list.toString());
console.log('remove element 11 => ', list.remove(11));
console.log('list.toString() => ', list.toString());
console.log('remove element 18 => ', list.remove(18));
console.log('list.toString() => ', list.toString());
Output
push element 15
list.indexOf(15) => 0
push element 10
list.toString() => 15,10
list.indexOf(10) => 1
push element 13
list.toString() => 15,10,13
list.indexOf(13) => 2
list.indexOf(10) => 1
push elements 11 and 12
list.toString() => 15,10,13,11,12
list.removeAt(1) => 10
list.toString() => 15,13,11,12
list.removeAt(3) => 12
list.toString() => 15,13,11
push element 14
list.toString() => 15,13,11,14
insert element 16 pos 0 => true
list.toString() => 16,15,13,11,14
insert element 17 pos 1 => true
list.toString() => 16,17,15,13,11,14
insert element 18 pos list.size() => true
list.toString() => 16,17,15,13,11,14,18
remove element 16 => 16
list.toString() => 17,15,13,11,14,18
remove element 11 => 11
list.toString() => 17,15,13,14,18
remove element 18 => 18
list.toString() => 17,15,13,14
Comments
Post a Comment
Leave Comment