Search code examples
sortinglinked-listpseudocode

problem while sorting a linked list (pseudocode)?


I was trying to figure out a way to sort a linked list in ascending or descending order, but because a linked list is accessed only sequentially, I don't know how to do it, let me explain it better, this is a code sketch of navigating a linked list in C (for the sake of this question, it's not important what list implementation do you use, it's only about the algorithm design of this specific problem):

Item* tmp = i; // i is a list, and tmp is a pointer to the list, 
while(!listisempty(tmp)) {
// do something
tmp = tmp->next; 
}

this is a possible way to navigate the linked list, I can only access the current element and the next element, i can't access directly the last element to sort the list efficiently,

Item* tmp = i; // i is a list, and tmp is a pointer to the list, 
    while(!listisempty(tmp)) {
    if (current > next) {
    swap(current, next);
}
    tmp = tmp->next; 
    }

but this idea is not efficient, because i have to navigate the linked list multiple times in order to sort the list.

is there a way of starting with an arbitrary element in the list in order to sort it?

[I can try the gnome sort (i.e stupid sort), but it's not efficient and therefore i've ignored it (plus, the list can be long and it may require a lot of steps)]


Solution

  • You are right that a linked list can only be traversed sequentially.

    However, there are sorting algorithms that don't need much else. A classic candidate for linked lists is merge sort. You can take the top-down approach or the bottom-up approach. A key concept is that you split the list into smaller lists, until your list has only one element, and can be considered sorted. True, to split a list in the middle, you'll have to traverse the list, but that should not be considered an issue.

    Then you only need a function that can merge two sorted linked lists, mutating the next property of the least node to the next least node, ...etc, so forming one merged, sorted list.

    If you keep doing that, you'll end up with a sorted linked list.

    This process has a time complexity of O(𝑛log𝑛), which is what can be expected of an efficient sorting algorithm.

    Alternatively, you can also look into ideas of quick sort: creating partitions would translate to creating separated lists, where you append elements to the correct partition-list depending on how they compare with a pivot.