diff --git a/src/data-structures/linked-list/LinkedList.js b/src/data-structures/linked-list/LinkedList.js index ba7d0e3ee..bef0d05c8 100644 --- a/src/data-structures/linked-list/LinkedList.js +++ b/src/data-structures/linked-list/LinkedList.js @@ -56,35 +56,53 @@ export default class LinkedList { /** * @param {*} value - * @param {number} index + * @param {number} rawIndex * @return {LinkedList} */ insert(value, rawIndex) { const index = rawIndex < 0 ? 0 : rawIndex; + + // If index is 0, prepend the value to the list. if (index === 0) { this.prepend(value); - } else { - let count = 1; - let currentNode = this.head; - const newNode = new LinkedListNode(value); - while (currentNode) { - if (count === index) break; - currentNode = currentNode.next; - count += 1; + return this; + } + + const newNode = new LinkedListNode(value); + let currentNode = this.head; + let count = 1; + + // Traverse the list to find the insertion point. + while (currentNode) { + if (count === index) break; + count += 1; + currentNode = currentNode.next; + } + + if (currentNode) { + // If currentNode is found, insert the newNode after it. + newNode.next = currentNode.next; + currentNode.next = newNode; + + // UPDATE: If the newNode is inserted after the current tail, + // we must update the tail to point to the newNode. + if (currentNode === this.tail) { + this.tail = newNode; } - if (currentNode) { - newNode.next = currentNode.next; - currentNode.next = newNode; + } else { + // If currentNode is not found (index out of bounds or empty list). + if (!this.tail) { + // Case for empty list: newNode becomes both head and tail. + this.head = newNode; + this.tail = newNode; } else { - if (this.tail) { - this.tail.next = newNode; - this.tail = newNode; - } else { - this.head = newNode; - this.tail = newNode; - } + // Case for index out of bounds: append the newNode to the end. + newNode.next = this.tail.next; + this.tail.next = newNode; + this.tail = newNode; } } + return this; } diff --git a/src/data-structures/linked-list/__test__/LinkedList.test.js b/src/data-structures/linked-list/__test__/LinkedList.test.js index 6ac41ddf0..546002cac 100644 --- a/src/data-structures/linked-list/__test__/LinkedList.test.js +++ b/src/data-structures/linked-list/__test__/LinkedList.test.js @@ -279,4 +279,24 @@ describe('LinkedList', () => { expect(linkedList.head.value).toBe(1); expect(linkedList.tail.value).toBe(3); }); + + it('should update tail when inserting at the end and keep it consistent for next appends', () => { + const linkedList = new LinkedList(); + + linkedList.append(1); + linkedList.append(2); + + // Insert 3 at index 2 (current tail position). + linkedList.insert(3, 2); + + // 1. Verify that the tail is pointing to 3. + expect(linkedList.tail.value).toBe(3); + expect(linkedList.toString()).toBe('1,2,3'); + + // 2. Ensure that subsequent appends work correctly without losing data. + // If the tail wasn't updated correctly, appending 4 would overwrite 3. + linkedList.append(4); + expect(linkedList.toString()).toBe('1,2,3,4'); + expect(linkedList.tail.value).toBe(4); + }); });