Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 37 additions & 19 deletions src/data-structures/linked-list/LinkedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
20 changes: 20 additions & 0 deletions src/data-structures/linked-list/__test__/LinkedList.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});