class Node {
constructor(value, label) {
this.value = value;
this.label = label; // to track original order
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
}
append(value, label) {
const newNode = new Node(value, label);
if (!this.head) {
this.head = newNode;
return;
}
let curr = this.head;
while (curr.next) {
curr = curr.next;
}
curr.next = newNode;
}
print() {
let curr = this.head;
let result = '';
while (curr) {
result += curr.value + curr.label + ' -> ';
curr = curr.next;
}
result += 'null';
console.log(result);
}
}
function stableSortLinkedList(list) {
if (!list.head || !list.head.next) return;
let changed;
do {
changed = false;
let curr = list.head;
while (curr.next) {
// Compare values
if (curr.value > curr.next.value) {
// Swap values and labels to keep nodes stable
[curr.value, curr.next.value] = [curr.next.value, curr.value];
[curr.label, curr.next.label] = [curr.next.label, curr.label];
changed = true;
}
curr = curr.next;
}
} while (changed);
}
// Driver code
const list = new LinkedList();
list.append(5, 'a');
list.append(3, '');
list.append(5, 'b');
list.append(2, '');
list.append(3, '');
console.log('Before sorting:');
list.print();
stableSortLinkedList(list);
console.log('After stable sorting:');
list.print();if (!list.head || !list.head.next) return;
handle empty or single node list - no sorting needed
do { changed = false; let curr = list.head; while (curr.next) { ... } } while (changed);
repeat passes until no swaps - bubble sort approach
if (curr.value > curr.next.value) { swap values and labels; changed = true; }
swap only if current value is greater to keep ascending order and maintain stability by swapping labels with values
advance to next node to compare pairs
Before sorting:
5a -> 3 -> 5b -> 2 -> 3 -> null
After stable sorting:
2 -> 3 -> 3 -> 5a -> 5b -> null