Intro
Last time, we learned how to push a new node to the end of our Singly Linked List.
Today, we learn how to pop something from the list. Pop
means remove something from the end
.
Current Code
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class SinglyLinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
push(value) {
const newNode = new Node(value);
if (this.length > 0) {
this.tail.next = newNode;
} else {
this.head = newNode;
}
this.tail = newNode;
this.length += 1;
return newNode;
}
}
Thoughts
First, we should think about the constraints and possibilities:
If there is currently NO other node in the Singly Linked List (so it is currently empty):
- return
null
, because we can't remove a node
If there is 1 node in the Singly Linked List:
- find the second to last node (it should become the new tail)
- set its
next
tonull
- set it as
tail
- decrease the Singly Linked List's
length
by 1 - set the Singly Linked List's
head
andtail
tonull
, because it is empty now - return the popped node
If there is more than 1 node in the Singly Linked List:
- find the second to last node (it should become the new tail)
- set its
next
tonull
- set it as
tail
- decrease the Singly Linked List's
length
by 1 - return the popped node
Examples:
- 0 nodes: before: null (head & tail) => after: null (head & tail)
- 1 node: before: A (head & tail) => after: null (head & tail)
- 2 nodes: before: A (head) -> B (tail) => after: A (head & tail)
- n nodes: before: A (head) -> ... -> n-1 -> n (tail) => after: A (head) -> ... -> n-1 (tail)
Implementation (Short version, DRY)
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class SinglyLinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
push(value) {
const newNode = new Node(value);
if (!this.length) {
this.head = newNode;
} else {
this.tail.next = newNode;
}
this.tail = newNode;
this.length += 1;
return newNode;
}
pop() {
// no node in the list, therefore return null
if (!this.length) {
return null;
} else {
/*
* find the second to last node (it should become the new tail):
* - set the current head as currentNode (we always have to start from the List's head node)
* - set the current head as secondToLastNode (we can't go back a node, therefore we have to save the second to last)
* - as long as the current node has a next node (so it is not the last node)
* - then set the current node to the second to last
* - then set the current node's `next` as the current node
*/
let currentNode = this.head;
let secondToLastNode = this.head;
while (currentNode.next) {
secondToLastNode = currentNode;
currentNode = currentNode.next;
}
// set the second to last node's `next` to `null` (the second to last should "cut" its connection to the next node)
secondToLastNode.next = null;
// set it as `tail`
this.tail = secondToLastNode;
// decrease the Singly Linked List's `length` by 1
this.length -= 1;
// if the Singly Linked List now is empty, set its `head` and `tail` to `null`
if (!this.length) {
this.head = null;
this.tail = null;
}
// return the popped node (found some lines above)
return currentNode;
}
}
}
Result
Let's have a look how to use the Singly Linked List pop
method and its results.
const newSLL = new SinglyLinkedList();
newSLL.push("1");
newSLL.push("2");
console.log(newSLL);
/* SinglyLinkedList {
* length: 2,
* head: Node { value: '1', next: Node { value: '2', next: null } },
* tail: Node { value: '2', next: null }
* }
*/
console.log(newSLL.pop()); // Node { value: '2', next: null }
console.log(newSLL.pop()); // Node { value: '1', next: null }
console.log(newSLL.pop()); // null
console.log(newSLL); // SinglyLinkedList { length: 0, head: null, tail: null }
Next Part
We will implement how to add a node to the beginning of the Singly Linked List. If you want to be notified, subscribe :)