Intro
Last time, we learned how to update/set a specific node.
Today, we learn how to insert a new node at any specific index.
Current Code
We start with code that has push
, unshift
and get
, because we can reuse these methods.
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; } unshift(value) { const newHead = new Node(value); if (!this.length) { this.head = newHead; this.tail = newHead; } else { newHead.next = this.head; this.head = newHead; } this.length += 1; return newHead; } get(index) { if (index < 0 || index >= this.length) { return null; } else { let count = 0; let currentNode = this.head; while (count < index) { currentNode = currentNode.next; count += 1; } return currentNode; } } }
Thoughts
First, we should think about the constraints and possibilities:
If we want to add a node "outside" the List (less than 0 or greater than the length of the current List):
- return null
If we want to add a node at the beginning of the List (index is 0):
- we can use our
unshift
method
If we want to add a node at the end of the List:
- we can use our
push
method
All remaining cases:
- create a new node
- put it between the node before the new node's place and the node, that is currently at this place
Example:
- current List: A -> B
- desired List: A -> N -> B
Steps:
- create new node
N
- point
N
'snext
toB
- point
A
'snext
toN
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; } unshift(value) { const newHead = new Node(value); if (!this.length) { this.head = newHead; this.tail = newHead; } else { newHead.next = this.head; this.head = newHead; } this.length += 1; return newHead; } get(index) { if (index < 0 || index >= this.length) { return null; } else { let count = 0; let currentNode = this.head; while (count < index) { currentNode = currentNode.next; count += 1; } return currentNode; } } insert(index, value) { // add a node "outside" the List (=> invalid) if (index < 0 || index > this.length) { return null; } else if (index === 0) { // add a node to the beginning of the List return this.unshift(value); } else if (index === this.length) { // add a node to the end of the List return this.push(value); } else { // get the node before the new node's desired place (because it has to point to the new node soon) const preDesiredPlace = this.get(index - 1); // create a new node const newNode = new Node(value); // the new node should point to the node, that is currently at the new node's desired place newNode.next = preDesiredPlace.next; // the node before the new node's desired place should point to the new node preDesiredPlace.next = newNode; // increase the List's length by 1 this.length += 1; // return the new node return newNode; } } }
Result
Let's have a look how to use the Singly Linked List's insert
method and its results.
const newSLL = new SinglyLinkedList(); console.log(newSLL.insert(0, "A")); // Node { value: 'A', next: null } console.log(newSLL.insert(1, "B")); // Node { value: 'B', next: null } console.log(newSLL); // SinglyLinkedList { // length: 2, // head: Node { value: 'A', next: Node { value: 'B', next: null } }, // tail: Node { value: 'B', next: null } // } console.log(newSLL.insert(1, "N (between A and B)")); // Node { // value: 'N (between A and B)', // next: Node { value: 'B', next: null } // } console.log(newSLL); // SinglyLinkedList { // length: 3, // head: Node { // value: 'A', // next: Node { value: 'N (between A and B)', next: [Node] } // }, // tail: Node { value: 'B', next: null } // }
Next Part
We will implement how to remove a node at a specific index. If you want to be notified, subscribe :)
Questions
We are doing it like:
- point
N
'snext
toB
- point
A
'snext
toN
What would happen, if we'd switch these steps?
Top comments (2)
we can use our pop method -> we can use our push method
Thanks Bruce,
fixed it.