class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedList {
constructor(value) {
// Allow empty list creation
if (value === undefined) {
this.head = null;
this.tail = null;
this.length = 0;
return;
}
const newNode = new Node(value);
this.head = newNode;
this.tail = newNode;
this.length = 1;
}
append(value) {
if (value === undefined) {
throw new Error("Cannot append undefined value");
}
const newNode = new Node(value);
// Handle empty list
if (this.length === 0) {
this.head = newNode;
this.tail = newNode;
this.length = 1;
return this;
}
this.tail.next = newNode;
this.tail = newNode;
this.length++;
return this;
}
prepend(value) {
if (value === undefined) {
throw new Error("Cannot prepend undefined value");
}
const newNode = new Node(value);
// Handle empty list
if (this.length === 0) {
this.head = newNode;
this.tail = newNode;
this.length = 1;
return this;
}
newNode.next = this.head;
this.head = newNode;
this.length++;
return this;
}
insert(index, value) {
if (!Number.isInteger(index)) {
throw new Error("Index must be an integer");
}
if (index < 0) {
throw new Error("Index cannot be negative");
}
if (value === undefined) {
throw new Error("Cannot insert undefined value");
}
// Insert at end
if (index >= this.length) {
return this.append(value);
}
// Insert at beginning
if (index === 0) {
return this.prepend(value);
}
const newNode = new Node(value);
const leader = this.traverseToIndex(index - 1);
const holdingPointer = leader.next;
leader.next = newNode;
newNode.next = holdingPointer;
this.length++;
return this;
}
traverseToIndex(index) {
if (this.length === 0) {
throw new Error("Cannot traverse an empty list");
}
if (!Number.isInteger(index)) {
throw new Error("Index must be an integer");
}
if (index < 0 || index >= this.length) {
throw new Error("Index out of bounds");
}
let counter = 0;
let currentNode = this.head;
while (counter !== index) {
currentNode = currentNode.next;
counter++;
}
return currentNode;
}
remove(index) {
if (this.length === 0) {
throw new Error("Cannot remove from an empty list");
}re
if (!Number.isInteger(index)) {
throw new Error("Index must be an integer");
}
if (index < 0 || index >= this.length) {
throw new Error("Index out of bounds");
}
// Remove head
if (index === 0) {
this.head = this.head.next;
this.length--;
// List became empty
if (this.length === 0) {
this.tail = null;
}
return this;
}
const leader = this.traverseToIndex(index - 1);
const unwantedNode = leader.next;
leader.next = unwantedNode.next;
// Removed tail
if (unwantedNode === this.tail) {
this.tail = leader;
}
this.length--;
return this;
}
reverse() {
// Empty list
if (this.length === 0) {
throw new Error("Cannot reverse an empty list");
}
// Single node list
if (this.length === 1) {
return this;
}
let first = this.head;
this.tail = this.head;
let second = first.next;
while (second !== null) {
const temp = second.next;
second.next = first;
first = second;
second = temp;
}
this.head.next = null;
this.head = first;
return this;
}
printList() {
const arr = [];
let currentNode = this.head;
while (currentNode !== null) {
arr.push(currentNode.value);
currentNode = currentNode.next;
}
console.log(arr);
return arr;
}
}
// Example usage
const myLinkedList = new LinkedList(10);
myLinkedList.append(5);
myLinkedList.append(16);
myLinkedList.prepend(1);
myLinkedList.insert(2, 99);
myLinkedList.remove(0);
myLinkedList.printList();
console.log(myLinkedList);