Introduction Link to heading

Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

Solution Link to heading

Quicksort:

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func sortList(head *ListNode) *ListNode {

    var last *ListNode
    for i := head; i != nil; i = i.Next {
        last = i
    }

    quicksort(head, last)
    return head
}

func quicksort(first *ListNode, last *ListNode) {
    if first == nil || first == last {
        return
    }
    if first.Next == last {
        if first.Val > last.Val {
            last.Val, first.Val = first.Val, last.Val
        }
        return
    }
    p, prev := partition(first, last)
    if prev != nil {
        quicksort(first, prev)
    }
    if p != last {
        quicksort(p.Next, last)
    }
}

func partition(first *ListNode, last *ListNode) (*ListNode, *ListNode) {
    pivot := last.Val
    var prev *ListNode
    i := first
    for j := first; j != last; j = j.Next {
        if j.Val < pivot {
            i.Val, j.Val = j.Val, i.Val
            prev = i
            i = i.Next
        }
    }
    i.Val, last.Val = last.Val, i.Val
    return i, prev
}

Mergesort:

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func sortList(head *ListNode) *ListNode {
    return mergesort(head, nil)
}

func mergesort(head, tail *ListNode) *ListNode {

    if head == tail {
        return nil
    }

    if head.Next == tail {
        return &ListNode{head.Val, nil}
    }

    if head.Next.Next == tail {
        first := head
        second := head.Next

        if first.Val > second.Val {
            first, second = second, first
        }
        return &ListNode{ first.Val, &ListNode{ second.Val, nil } }
    }

    slow, fast := head, head
    for ; fast != tail; slow = slow.Next {
        fast = fast.Next
        if fast != tail {
            fast = fast.Next
        }
    }

    left := mergesort(head, slow)
    right := mergesort(slow, tail)

    return merge(left, right)
}

func merge(left, right *ListNode) *ListNode {

    var root, node *ListNode
    i, j := left, right

    for {
        var add *ListNode

        if i != nil {
            if j != nil {
                if i.Val < j.Val {
                    add = i
                    i = i.Next
                } else {
                    add = j
                    j = j.Next
                }
            } else {
                add = i
                i = i.Next                
            }
        } else if j != nil {
            add = j
            j = j.Next            
        } else {
            break
        }
        if root == nil {
            root = &ListNode{ add.Val, nil }
            node = root
        } else {
            node.Next = &ListNode{ add.Val, nil }
            node = node.Next
        }
    }

    return root
}

Explanation Link to heading

Quick sort solution on each iteration takes last element in the range and compare other elements with this one by divinding the range for lower and higher. That selected element has a fixed position in finally sorted array.

Merge sort is another faster solution, it works better because it constantly has complexity O(nlog(n)), whereas quicksort in some cases can have complexity up to O(nn)