Absolute List Sorting

Last Updated : 22 Aug, 2026

Given head of a linked list that is sorted based on absolute values. Sort the list based on actual values.

Examples:

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

213

Explanation: Actual sorted order of [1, -2, -3, 4, -5] is [-5, -3, -2, 1, 4].

Input: head: 5 -> -10
Output: -10 -> 5

214

Explanation: Actual sorted order of [5, -10] is [-10, 5].

Try It Yourself
redirect icon

[Naive Approach] Using Merge Sort - O(n * log n) Time and O(log n) Space

The idea is to use Merge Sort. Merge Sort is particularly suitable for linked lists because we can split the list using slow/fast pointers and merge the sorted halves using only pointer manipulation.

We recursively divide the list into smaller halves until each part contains one node. Then we merge the halves by comparing their actual values, producing a completely sorted linked list.

  • Find the middle of the linked list using slow and fast pointers.
  • Split the list into two halves.
  • Recursively sort both halves based on actual values.
  • Merge the two sorted halves by comparing node values.
  • Continue merging until all nodes are combined.
  • Return the head of the merged sorted list.
C++
#include <iostream>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

// Merge two sorted linked lists.
Node *mergeLists(Node *a, Node *b)
{
    if (a == nullptr)
        return b;

    if (b == nullptr)
        return a;

    // Choose the smaller node.
    if (a->data <= b->data)
    {
        a->next = mergeLists(a->next, b);
        return a;
    }
    else
    {
        b->next = mergeLists(a, b->next);
        return b;
    }
}

// Find the middle of the linked list.
Node *getMiddle(Node *head)
{
    Node *slow = head;
    Node *fast = head->next;

    while (fast != nullptr && fast->next != nullptr)
    {
        slow = slow->next;
        fast = fast->next->next;
    }

    return slow;
}

// Sort the linked list using Merge Sort.
Node *sortList(Node *head)
{
    // Base case.
    if (head == nullptr || head->next == nullptr)
        return head;

    // Find the middle.
    Node *middle = getMiddle(head);

    // Split the list into two halves.
    Node *right = middle->next;
    middle->next = nullptr;

    // Recursively sort both halves.
    Node *left = sortList(head);
    right = sortList(right);

    // Merge the sorted halves.
    return mergeLists(left, right);
}

void printList(Node *head)
{
    while (head != nullptr)
    {
        cout << head->data;

        if (head->next != nullptr)
            cout << " -> ";

        head = head->next;
    }

    cout << endl;
}

int main()
{
    Node *head = new Node(0);
    head->next = new Node(1);
    head->next->next = new Node(-2);
    head->next->next->next = new Node(3);
    head->next->next->next->next = new Node(-4);
    head->next->next->next->next->next = new Node(5);

    head = sortList(head);

    printList(head);

    return 0;
}
Java
class Node {
    int data;
    Node next;

    Node(int x)
    {
        data = x;
        next = null;
    }
}

class GFG {

    // Merge two sorted linked lists.
    static Node mergeLists(Node a, Node b)
    {
        if (a == null)
            return b;

        if (b == null)
            return a;

        // Choose the smaller node.
        if (a.data <= b.data) {
            a.next = mergeLists(a.next, b);
            return a;
        }
        else {
            b.next = mergeLists(a, b.next);
            return b;
        }
    }

    // Find the middle of the linked list.
    static Node getMiddle(Node head)
    {
        Node slow = head;
        Node fast = head.next;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        return slow;
    }

    // Sort the linked list using Merge Sort.
    static Node sortList(Node head)
    {
        // Base case.
        if (head == null || head.next == null)
            return head;

        // Find the middle.
        Node middle = getMiddle(head);

        // Split the list into two halves.
        Node right = middle.next;
        middle.next = null;

        // Recursively sort both halves.
        Node left = sortList(head);
        right = sortList(right);

        // Merge the sorted halves.
        return mergeLists(left, right);
    }

    static void printList(Node head)
    {
        while (head != null) {
            System.out.print(head.data);

            if (head.next != null)
                System.out.print(" -> ");

            head = head.next;
        }

        System.out.println();
    }

    public static void main(String[] args)
    {
        Node head = new Node(0);
        head.next = new Node(1);
        head.next.next = new Node(-2);
        head.next.next.next = new Node(3);
        head.next.next.next.next = new Node(-4);
        head.next.next.next.next.next = new Node(5);

        head = sortList(head);

        printList(head);
    }
}
Python
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


# Merge two sorted linked lists.
def merge_lists(a, b):
    if a is None:
        return b

    if b is None:
        return a

    # Choose the smaller node.
    if a.data <= b.data:
        a.next = merge_lists(a.next, b)
        return a
    else:
        b.next = merge_lists(a, b.next)
        return b


# Find the middle of the linked list.
def get_middle(head):
    slow = head
    fast = head.next

    while fast is not None and fast.next is not None:
        slow = slow.next
        fast = fast.next.next

    return slow


# Sort the linked list using Merge Sort.
def sortList(head):

    # Base case.
    if head is None or head.next is None:
        return head

    # Find the middle.
    middle = get_middle(head)

    # Split the list into two halves.
    right = middle.next
    middle.next = None

    # Recursively sort both halves.
    left = sortList(head)
    right = sortList(right)

    # Merge the sorted halves.
    return merge_lists(left, right)


def print_list(head):
    while head is not None:
        print(head.data, end="")

        if head.next is not None:
            print(" -> ", end="")

        head = head.next

    print()


# Driver Code
if __name__ == "__main__":
    
    # Create the linked list.
    head = Node(0)
    head.next = Node(1)
    head.next.next = Node(-2)
    head.next.next.next = Node(3)
    head.next.next.next.next = Node(-4)
    head.next.next.next.next.next = Node(5)

    head = sortList(head)

    print_list(head)
C#
using System;

class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}


class GFG {

    // Merge two sorted linked lists.
    static Node MergeLists(Node a, Node b)
    {
        if (a == null)
            return b;

        if (b == null)
            return a;

        // Choose the smaller node.
        if (a.data <= b.data) {
            a.next = MergeLists(a.next, b);
            return a;
        }
        else {
            b.next = MergeLists(a, b.next);
            return b;
        }
    }

    // Find the middle of the linked list.
    static Node GetMiddle(Node head)
    {
        Node slow = head;
        Node fast = head.next;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        return slow;
    }

    // Sort the linked list using Merge Sort.
    static Node sortList(Node head)
    {
        // Base case.
        if (head == null || head.next == null)
            return head;

        // Find the middle.
        Node middle = GetMiddle(head);

        // Split the list into two halves.
        Node right = middle.next;
        middle.next = null;

        // Recursively sort both halves.
        Node left = sortList(head);
        right = sortList(right);

        // Merge the sorted halves.
        return MergeLists(left, right);
    }

    static void PrintList(Node head)
    {
        while (head != null) {
            Console.Write(head.data);

            if (head.next != null)
                Console.Write(" -> ");

            head = head.next;
        }

        Console.WriteLine();
    }

    static void Main()
    {
        Node head = new Node(0);
        head.next = new Node(1);
        head.next.next = new Node(-2);
        head.next.next.next = new Node(3);
        head.next.next.next.next = new Node(-4);
        head.next.next.next.next.next = new Node(5);

        head = sortList(head);

        PrintList(head);
    }
}
JavaScript
class Node {
    constructor(data)
    {
        this.data = data;
        this.next = null;
    }
}

// Merge two sorted linked lists.
function mergeLists(a, b)
{
    if (a === null)
        return b;

    if (b === null)
        return a;

    // Choose the smaller node.
    if (a.data <= b.data) {
        a.next = mergeLists(a.next, b);
        return a;
    }
    else {
        b.next = mergeLists(a, b.next);
        return b;
    }
}

// Find the middle of the linked list.
function getMiddle(head)
{
    let slow = head;
    let fast = head.next;

    while (fast !== null && fast.next !== null) {
        slow = slow.next;
        fast = fast.next.next;
    }

    return slow;
}

// Sort the linked list using Merge Sort.
function sortList(head)
{
    // Base case.
    if (head === null || head.next === null)
        return head;

    // Find the middle.
    const middle = getMiddle(head);

    // Split the list into two halves.
    let right = middle.next;
    middle.next = null;

    // Recursively sort both halves.
    const left = sortList(head);
    right = sortList(right);

    // Merge the sorted halves.
    return mergeLists(left, right);
}

function printList(head)
{
    const result = [];

    while (head !== null) {
        result.push(head.data);
        head = head.next;
    }

    console.log(result.join(" -> "));
}

// Driver Code

// Create the linked list.
let head = new Node(0);
head.next = new Node(1);
head.next.next = new Node(-2);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(-4);
head.next.next.next.next.next = new Node(5);

head = sortList(head);

printList(head);

Output
-4 -> -2 -> 0 -> 1 -> 3 -> 5

[Expected Approach] Move Negative Nodes to Front - O(n) Time and O(1) Space

Since the list is sorted by absolute values, the non-negative nodes are already in increasing order, while the negative nodes appear in decreasing actual order.

So, the idea is to traverse the list and whenever a node is smaller than the previous node, we move it to the front. Such a node must be negative, and moving all such nodes to the front reverses their order automatically.

  • Start with prev = head and curr = head->next.
  • Traverse the linked list from left to right.
  • If curr->data < prev->data, detach curr from its current position.
  • Insert curr at the beginning of the list.
  • Set curr back to prev and continue traversing.
  • Return the updated head.
C++
#include <iostream>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

// Sort the linked list based on actual values.
// The given list is already sorted by absolute values.
Node *sortList(Node *head)
{
    // Handle empty or single-node list.
    if (head == nullptr || head->next == nullptr)
        return head;

    Node *prev = head;
    Node *curr = head->next;

    while (curr != nullptr)
    {
        // If current node is smaller than the previous node,
        // move it to the beginning of the list.
        if (curr->data < prev->data)
        {
            // Detach curr from its current position.
            prev->next = curr->next;

            // Insert curr at the beginning.
            curr->next = head;
            head = curr;

            // Continue checking from prev.
            curr = prev;
        }
        else
        {
            // Current node is already in the correct position.
            prev = curr;
        }

        curr = curr->next;
    }

    return head;
}

void printList(Node *head)
{
    while (head != nullptr)
    {
        cout << head->data;

        if (head->next != nullptr)
            cout << " -> ";

        head = head->next;
    }

    cout << endl;
}

int main()
{
    Node *head = new Node(0);
    head->next = new Node(1);
    head->next->next = new Node(-2);
    head->next->next->next = new Node(3);
    head->next->next->next->next = new Node(-4);
    head->next->next->next->next->next = new Node(5);

    head = sortList(head);

    printList(head);

    return 0;
}
Java
class Node {
    int data;
    Node next;

    Node(int x)
    {
        data = x;
        next = null;
    }
}


class GFG {

    // Sort the linked list based on actual values.
    // The given list is already sorted by absolute values.
    static Node sortList(Node head)
    {
        // Handle empty or single-node list.
        if (head == null || head.next == null)
            return head;

        Node prev = head;
        Node curr = head.next;

        while (curr != null) {

            // If current node is smaller than the previous
            // node, move it to the beginning.
            if (curr.data < prev.data) {

                // Detach curr from its current position.
                prev.next = curr.next;

                // Insert curr at the beginning.
                curr.next = head;
                head = curr;

                // Continue checking from prev.
                curr = prev;
            }
            else {
                // Current node is already in the correct
                // position.
                prev = curr;
            }

            curr = curr.next;
        }

        return head;
    }

    static void printList(Node head)
    {
        while (head != null) {
            System.out.print(head.data);

            if (head.next != null)
                System.out.print(" -> ");

            head = head.next;
        }

        System.out.println();
    }

    public static void main(String[] args)
    {
        Node head = new Node(0);
        head.next = new Node(1);
        head.next.next = new Node(-2);
        head.next.next.next = new Node(3);
        head.next.next.next.next = new Node(-4);
        head.next.next.next.next.next = new Node(5);

        head = sortList(head);
        printList(head);
    }
}
Python
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


# Sort the linked list based on actual values.
# The given list is already sorted by absolute values.
def sortList(head):

    # Handle empty or single-node list.
    if head is None or head.next is None:
        return head

    prev = head
    curr = head.next

    while curr is not None:

        # If current node is smaller than the previous node,
        # move it to the beginning.
        if curr.data < prev.data:

            # Detach curr from its current position.
            prev.next = curr.next

            # Insert curr at the beginning.
            curr.next = head
            head = curr

            # Continue checking from prev.
            curr = prev

        else:
            # Current node is already in the correct position.
            prev = curr

        curr = curr.next

    return head


def print_list(head):
    while head is not None:
        print(head.data, end="")

        if head.next is not None:
            print(" -> ", end="")

        head = head.next

    print()

# Driver Code
if __name__ == "__main__":
    
 # Create the linked list.
 head = Node(0)
 head.next = Node(1)
 head.next.next = Node(-2)
 head.next.next.next = Node(3)
 head.next.next.next.next = Node(-4)
 head.next.next.next.next.next = Node(5)

 head = sortList(head)
 print_list(head)
C#
using System;

class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}


class GFG {

    // Sort the linked list based on actual values.
    // The given list is already sorted by absolute values.
    static Node sortList(Node head)
    {
        // Handle empty or single-node list.
        if (head == null || head.next == null)
            return head;

        Node prev = head;
        Node curr = head.next;

        while (curr != null) {
            // If current node is smaller than the previous
            // node, move it to the beginning.
            if (curr.data < prev.data) {
                // Detach curr from its current position.
                prev.next = curr.next;

                // Insert curr at the beginning.
                curr.next = head;
                head = curr;

                // Continue checking from prev.
                curr = prev;
            }
            else {
                // Current node is already in the correct
                // position.
                prev = curr;
            }

            curr = curr.next;
        }

        return head;
    }

    static void PrintList(Node head)
    {
        while (head != null) {
            Console.Write(head.data);

            if (head.next != null)
                Console.Write(" -> ");

            head = head.next;
        }

        Console.WriteLine();
    }

    static void Main()
    {
        Node head = new Node(0);
        head.next = new Node(1);
        head.next.next = new Node(-2);
        head.next.next.next = new Node(3);
        head.next.next.next.next = new Node(-4);
        head.next.next.next.next.next = new Node(5);

        head = sortList(head);
        PrintList(head);
    }
}
JavaScript
class Node {
    constructor(data)
    {
        this.data = data;
        this.next = null;
    }
}

// Sort the linked list based on actual values.
// The given list is already sorted by absolute values.
function sortList(head)
{
    // Handle empty or single-node list.
    if (head === null || head.next === null)
        return head;

    let prev = head;
    let curr = head.next;

    while (curr !== null) {

        // If current node is smaller than the previous
        // node, move it to the beginning.
        if (curr.data < prev.data) {

            // Detach curr from its current position.
            prev.next = curr.next;

            // Insert curr at the beginning.
            curr.next = head;
            head = curr;

            // Continue checking from prev.
            curr = prev;
        }
        else {
            // Current node is already in the correct
            // position.
            prev = curr;
        }

        curr = curr.next;
    }

    return head;
}

function printList(head)
{
    let result = [];

    while (head !== null) {
        result.push(head.data);
        head = head.next;
    }

    console.log(result.join(" -> "));
}

// Driver Code

// Create the linked list.
let head = new Node(0);
head.next = new Node(1);
head.next.next = new Node(-2);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(-4);
head.next.next.next.next.next = new Node(5);

head = sortList(head);
printList(head);

Output
-4 -> -2 -> 0 -> 1 -> 3 -> 5
Comment