Sort a linked list that is sorted alternating ascending and descending orders? - GeeksforGeeks

20 Jan, 2022
Given a Linked List. The Linked List is in alternating ascending and descending orders. Sort the list efficiently. Example: 
Input List: 10 -> 40 -> 53 -> 30 -> 67 -> 12 -> 89 -> NULL
Output List: 10 -> 12 -> 30 -> 40 -> 53 -> 67 -> 89 -> NULL

Input List: 1 -> 4 -> 3 -> 2 -> 5 -> NULL
Output List: 1 -> 2 -> 3 -> 4 -> 5 -> NULL
Simple Solution Approach: The basic idea is to apply to merge sort on the linked list. The implementation is discussed in this article: Merge Sort for linked List.Complexity Analysis:  
Time Complexity: The merge sort of linked list takes O(n log n) time. In the merge sort tree, the height is log n. Sorting each level will take O(n) time. So time complexity is O(n log n).
Auxiliary Space: O(n log n), In the merge sort tree the height is log n. Storing each level will take O(n) space. So space complexity is O(n log n).
Efficient Solution Approach:  
Separate two lists.Reverse the one with descending orderMerge both lists.
Separate two lists.
Reverse the one with descending order
Merge both lists.
Diagram: 
Below are the implementations of the above algorithm: 
C++
Java
Python3
C#
Javascript
// C++ program to sort a linked// list that is alternatively// sorted in increasing and decreasing order#include <bits/stdc++.h>using namespace std; // Linked list nodestruct Node {    int data;    struct Node* next;}; Node* mergelist(Node* head1, Node* head2);void splitList(Node* head, Node** Ahead, Node** Dhead);void reverselist(Node*& head); // This is the main function that sorts the// linked listvoid sort(Node** head){    // Split the list into lists    Node *Ahead, *Dhead;    splitList(*head, &Ahead, &Dhead);     // Reverse the descending linked list    reverselist(Dhead);     // Merge the two linked lists    *head = mergelist(Ahead, Dhead);} // A utility function to create a new nodeNode* newNode(int key){    Node* temp = new Node;    temp->data = key;    temp->next = NULL;    return temp;} // A utility function to reverse a linked listvoid reverselist(Node*& head){    Node *prev = NULL, *curr = head, *next;    while (curr) {        next = curr->next;        curr->next = prev;        prev = curr;        curr = next;    }    head = prev;} // A utility function to print a linked listvoid printlist(Node* head){    while (head != NULL) {        cout << head->data << " ";        head = head->next;    }    cout << endl;} // A utility function to merge two sorted linked listsNode* mergelist(Node* head1, Node* head2){    // Base cases    if (!head1)        return head2;    if (!head2)        return head1;     Node* temp = NULL;    if (head1->data < head2->data) {        temp = head1;        head1->next = mergelist(head1->next, head2);    }    else {        temp = head2;        head2->next = mergelist(head1, head2->next);    }    return temp;} // This function alternatively splits// a linked list with head as head into two:// For example, 10->20->30->15->40->7 \// is splitted into 10->30->40// and 20->15->7// "Ahead" is reference to head of ascending linked list// "Dhead" is reference to head of descending linked listvoid splitList(Node* head, Node** Ahead, Node** Dhead){    // Create two dummy nodes to initialize    // heads of two linked list    *Ahead = newNode(0);    *Dhead = newNode(0);     Node* ascn = *Ahead;    Node* dscn = *Dhead;    Node* curr = head;     // Link alternate nodes    while (curr) {        // Link alternate nodes of ascending linked list        ascn->next = curr;        ascn = ascn->next;        curr = curr->next;         // Link alternate nodes of descending linked list        if (curr) {            dscn->next = curr;            dscn = dscn->next;            curr = curr->next;        }    }     ascn->next = NULL;    dscn->next = NULL;    *Ahead = (*Ahead)->next;    *Dhead = (*Dhead)->next;} // Driver program to test above functionint main(){    Node* head = newNode(10);    head->next = newNode(40);    head->next->next = newNode(53);    head->next->next->next = newNode(30);    head->next->next->next->next = newNode(67);    head->next->next->next->next->next = newNode(12);    head->next->next->next->next->next->next = newNode(89);     cout << "Given Linked List is " << endl;    printlist(head);     sort(&head);     cout << "Sorted Linked List is " << endl;    printlist(head);     return 0;}
// Java program to sort a// linked list that is alternatively// sorted in increasing and decreasing orderclass LinkedList {    Node head; // head of list     /* Linked list Node*/    class Node {        int data;        Node next;        Node(int d)        {            data = d;            next = null;        }    }     Node newNode(int key)    {        return new Node(key);    }     /* This is the main function that sorts       the linked list.*/    void sort()    {        /* Create 2 dummy nodes and initialise as           heads of linked lists */        Node Ahead = new Node(0), Dhead = new Node(0);         // Split the list into lists        splitList(Ahead, Dhead);         Ahead = Ahead.next;        Dhead = Dhead.next;         // reverse the descending list        Dhead = reverseList(Dhead);         // merge the 2 linked lists        head = mergeList(Ahead, Dhead);    }     /* Function to reverse the linked list */    Node reverseList(Node Dhead)    {        Node current = Dhead;        Node prev = null;        Node next;        while (current != null) {            next = current.next;            current.next = prev;            prev = current;            current = next;        }        Dhead = prev;        return Dhead;    }     /* Function to print linked list */    void printList()    {        Node temp = head;        while (temp != null) {            System.out.print(temp.data + " ");            temp = temp.next;        }        System.out.println();    }     // A utility function to merge    // two sorted linked lists    Node mergeList(Node head1, Node head2)    {        // Base cases        if (head1 == null)            return head2;        if (head2 == null)            return head1;         Node temp = null;        if (head1.data < head2.data) {            temp = head1;            head1.next = mergeList(head1.next, head2);        }        else {            temp = head2;            head2.next = mergeList(head1, head2.next);        }        return temp;    }     // This function alternatively splits    // a linked list with head as head into two:    // For example, 10->20->30->15->40->7 is    // splitted into 10->30->40    // and 20->15->7    // "Ahead" is reference to head of ascending linked list    // "Dhead" is reference to head of descending linked list    void splitList(Node Ahead, Node Dhead)    {        Node ascn = Ahead;        Node dscn = Dhead;        Node curr = head;         // Link alternate nodes         while (curr != null) {            // Link alternate nodes in ascending order            ascn.next = curr;            ascn = ascn.next;            curr = curr.next;             if (curr != null) {                dscn.next = curr;                dscn = dscn.next;                curr = curr.next;            }        }         ascn.next = null;        dscn.next = null;    }     /* Driver program to test above functions */    public static void main(String args[])    {        LinkedList llist = new LinkedList();        llist.head = llist.newNode(10);        llist.head.next = llist.newNode(40);        llist.head.next.next = llist.newNode(53);        llist.head.next.next.next = llist.newNode(30);        llist.head.next.next.next.next = llist.newNode(67);        llist.head.next.next.next.next.next = llist.newNode(12);        llist.head.next.next.next.next.next.next = llist.newNode(89);         System.out.println("Given linked list");        llist.printList();         llist.sort();         System.out.println("Sorted linked list");        llist.printList();    } } /* This code is contributed by Rajat Mishra */
# Python program to sort a linked list that is alternatively# sorted in increasing and decreasing orderclass LinkedList(object):    def __init__(self):        self.head = None     # Linked list Node    class Node(object):        def __init__(self, d):            self.data = d            self.next = None     def newNode(self, key):        return self.Node(key)     # This is the main function that sorts    # the linked list.    def sort(self):        # Create 2 dummy nodes and initialise as        # heads of linked lists        Ahead = self.Node(0)        Dhead = self.Node(0)        # Split the list into lists        self.splitList(Ahead, Dhead)        Ahead = Ahead.next        Dhead = Dhead.next        # reverse the descending list        Dhead = self.reverseList(Dhead)        # merge the 2 linked lists        self.head = self.mergeList(Ahead, Dhead)     # Function to reverse the linked list    def reverseList(self, Dhead):        current = Dhead        prev = None        while current != None:            self._next = current.next            current.next = prev            prev = current            current = self._next        Dhead = prev        return Dhead     # Function to print linked list    def printList(self):        temp = self.head        while temp != None:            print (temp.data,end=" ")            temp = temp.next        print()     # A utility function to merge two sorted linked lists    def mergeList(self, head1, head2):        # Base cases        if head1 == None:            return head2        if head2 == None:            return head1        temp = None        if head1.data < head2.data:            temp = head1            head1.next = self.mergeList(head1.next, head2)        else:            temp = head2            head2.next = self.mergeList(head1, head2.next)        return temp     # This function alternatively splits a linked list with head    # as head into two:    # For example, 10->20->30->15->40->7 is splitted into 10->30->40    # and 20->15->7    # "Ahead" is reference to head of ascending linked list    # "Dhead" is reference to head of descending linked list    def splitList(self, Ahead, Dhead):        ascn = Ahead        dscn = Dhead        curr = self.head        # Link alternate nodes        while curr != None:            # Link alternate nodes in ascending order            ascn.next = curr            ascn = ascn.next            curr = curr.next            if curr != None:                dscn.next = curr                dscn = dscn.next                curr = curr.next        ascn.next = None        dscn.next = None # Driver programllist = LinkedList()llist.head = llist.newNode(10)llist.head.next = llist.newNode(40)llist.head.next.next = llist.newNode(53)llist.head.next.next.next = llist.newNode(30)llist.head.next.next.next.next = llist.newNode(67)llist.head.next.next.next.next.next = llist.newNode(12)llist.head.next.next.next.next.next.next = llist.newNode(89) print ('Given linked list')llist.printList() llist.sort() print ('Sorted linked list')llist.printList() # This code is contributed by BHAVYA JAIN
// C# program to sort a linked list that is alternatively// sorted in increasing and decreasing orderusing System;class LinkedList {    Node head; // head of list     /* Linked list Node*/    public class Node {        public int data;        public Node next;        public Node(int d)        {            data = d;            next = null;        }    }     Node newNode(int key)    {        return new Node(key);    }     /* This is the main function that sorts    the linked list.*/    void sort()    {        /* Create 2 dummy nodes and initialise as        heads of linked lists */        Node Ahead = new Node(0), Dhead = new Node(0);         // Split the list into lists        splitList(Ahead, Dhead);         Ahead = Ahead.next;        Dhead = Dhead.next;         // reverse the descending list        Dhead = reverseList(Dhead);         // merge the 2 linked lists        head = mergeList(Ahead, Dhead);    }     /* Function to reverse the linked list */    Node reverseList(Node Dhead)    {        Node current = Dhead;        Node prev = null;        Node next;        while (current != null) {            next = current.next;            current.next = prev;            prev = current;            current = next;        }        Dhead = prev;        return Dhead;    }     /* Function to print linked list */    void printList()    {        Node temp = head;        while (temp != null) {            Console.Write(temp.data + " ");            temp = temp.next;        }        Console.WriteLine();    }     // A utility function to merge two sorted linked lists    Node mergeList(Node head1, Node head2)    {        // Base cases        if (head1 == null)            return head2;        if (head2 == null)            return head1;         Node temp = null;        if (head1.data < head2.data) {            temp = head1;            head1.next = mergeList(head1.next, head2);        }        else {            temp = head2;            head2.next = mergeList(head1, head2.next);        }        return temp;    }     // This function alternatively splits a linked list with head    // as head into two:    // For example, 10->20->30->15->40->7 is splitted into 10->30->40    // and 20->15->7    // "Ahead" is reference to head of ascending linked list    // "Dhead" is reference to head of descending linked list    void splitList(Node Ahead, Node Dhead)    {        Node ascn = Ahead;        Node dscn = Dhead;        Node curr = head;         // Link alternate nodes         while (curr != null) {            // Link alternate nodes in ascending order            ascn.next = curr;            ascn = ascn.next;            curr = curr.next;             if (curr != null) {                dscn.next = curr;                dscn = dscn.next;                curr = curr.next;            }        }         ascn.next = null;        dscn.next = null;    }     /* Driver code */    public static void Main(String[] args)    {        LinkedList llist = new LinkedList();        llist.head = llist.newNode(10);        llist.head.next = llist.newNode(40);        llist.head.next.next = llist.newNode(53);        llist.head.next.next.next = llist.newNode(30);        llist.head.next.next.next.next = llist.newNode(67);        llist.head.next.next.next.next.next = llist.newNode(12);        llist.head.next.next.next.next.next.next = llist.newNode(89);         Console.WriteLine("Given linked list");        llist.printList();         llist.sort();         Console.WriteLine("Sorted linked list");        llist.printList();    }} /* This code is contributed by Arnab Kundu */
<script>// javascript program to sort a// linked list that is alternatively// sorted in increasing and decreasing order     var head; // head of list     /* Linked list Node */     class Node {            constructor(val) {                this.data = val;                this.next = null;            }     }     function newNode(key) {        return new Node(key);    }     /*     * This is the main function that sorts the linked list.     */    function sort() {        /*         * Create 2 dummy nodes and initialise as heads of linked lists         */        var Ahead = new Node(0), Dhead = new Node(0);         // Split the list into lists        splitList(Ahead, Dhead);         Ahead = Ahead.next;        Dhead = Dhead.next;         // reverse the descending list        Dhead = reverseList(Dhead);         // merge the 2 linked lists        head = mergeList(Ahead, Dhead);    }     /* Function to reverse the linked list */    function reverseList(Dhead) {        var current = Dhead;        var prev = null;        var next;        while (current != null) {            next = current.next;            current.next = prev;            prev = current;            current = next;        }        Dhead = prev;        return Dhead;    }     /* Function to print linked list */    function printList() {        var temp = head;        while (temp != null) {            document.write(temp.data + " ");            temp = temp.next;        }        document.write();    }     // A utility function to merge    // two sorted linked lists    function mergeList(head1,  head2) {        // Base cases        if (head1 == null)            return head2;        if (head2 == null)            return head1;         var temp = null;        if (head1.data < head2.data) {            temp = head1;            head1.next = mergeList(head1.next, head2);        } else {            temp = head2;            head2.next = mergeList(head1, head2.next);        }        return temp;    }     // This function alternatively splits    // a linked list with head as head into two:    // For example, 10->20->30->15->40->7 is    // splitted into 10->30->40    // and 20->15->7    // "Ahead" is reference to head of ascending linked list    // "Dhead" is reference to head of descending linked list    function splitList(Ahead,  Dhead) {        var ascn = Ahead;        var dscn = Dhead;        var curr = head;         // Link alternate nodes         while (curr != null) {            // Link alternate nodes in ascending order            ascn.next = curr;            ascn = ascn.next;            curr = curr.next;             if (curr != null) {                dscn.next = curr;                dscn = dscn.next;                curr = curr.next;            }        }         ascn.next = null;        dscn.next = null;    }     /* Driver program to test above functions */                  head = newNode(10);        head.next = newNode(40);        head.next.next = newNode(53);        head.next.next.next = newNode(30);        head.next.next.next.next = newNode(67);        head.next.next.next.next.next = newNode(12);        head.next.next.next.next.next.next = newNode(89);         document.write("Given linked list<br/>");        printList();         sort();         document.write("<br/>Sorted linked list<br/>");        printList(); // This code contributed by aashish1995</script>
Output: 
Given Linked List is
10 40 53 30 67 12 89
Sorted Linked List is
10 12 30 40 53 67 89
Complexity Analysis:  
Time Complexity: O(n). One traversal is needed to separate the list and reverse them. The merging of sorted lists takes O(n) time.
Auxiliary Space: O(1). No extra space is required.
Thanks to Gaurav Ahirwar for suggesting this method.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
andrew1234
nidhi_biet
themaniac
aashish1995
ankita_saini
amartyaghoshgfg
Amazon
Linked-List-Sorting
Merge Sort
Linked List
Sorting
Amazon
Linked List
Sorting
Merge Sort
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
LinkedList in Java
Linked List vs Array
Delete a Linked List node at a given position
Implementing a Linked List in Java using Class
Queue - Linked List Implementation