After implementing a linked list in two different ways using Javascript, I found myself in a state of confusion about the inner workings of the code.
Trying to mentally visualize the creation process and the memory addresses being referenced proved to be a challenging task, especially considering the concept of passing by reference.
- Are both implementations technically correct?
- Although they appear to achieve the same results, do they operate differently under the surface?
- In the first option, specifically in the prepend() method, a new object is created in memory where the "next" property points to the existing memory address of the "head" property, while the "head" property is then pointed to the newly created object. At a glance, it might seem like a circular reference, but somehow it still works. How is this possible?
The key variations lie within the append() and prepend() methods.
Option 1:
class myLinkedList {
constructor(value) {
this.head = {
value: value,
next: null
}
this.tail = this.head;
}
append(element){
this.tail.next = {
value: element,
next: null
}
this.tail = this.tail.next;
}
prepend(element) {
const newObj = {
value: element,
next: this.head
}
this.head = newObj;
}
}
const linkedList = new myLinkedList(1);
linkedList.append(2);
linkedList.prepend(0);
Option 2:
class myLinkedList {
constructor(value) {
this.head = {
value: value,
next: null
}
this.tail = this.head;
}
append(element){
const newNode = {
value: element,
next: null
}
this.tail.next = newNode;
this.tail = newNode;
}
prepend(element) {
const newNode = {
value: element,
next: null
}
newNode.next = this.head;
this.head = newNode;
}
}
const linkedList = new myLinkedList(1);
linkedList.append(2);
linkedList.prepend(0);