Open In App

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

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:  

Efficient Solution:

Approach:  

  1. Separate two lists.
  2. Reverse the one with descending order
  3. Merge both lists.

Diagram: 

Below are the implementations of the above algorithm: 




// 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 node
struct 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 list
void 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 node
Node* newNode(int key)
{
    Node* temp = new Node;
    temp->data = key;
    temp->next = NULL;
    return temp;
}
  
// A utility function to reverse a linked list
void 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 list
void printlist(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}
  
// A utility function to merge two sorted linked lists
Node* 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 list
void 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 function
int 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 order
import java.io.*;
public class 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 dummyHead = new Node(0);
        Node temp = dummyHead;
        while(head1 != null && head2 != null) {
            if (head1.data <= head2.data) {
                temp.next = head1;
                head1 = head1.next;
            } else {
                temp.next = head2;
                head2 = head2.next;
            }
            temp = temp.next;
        }
          
        temp.next = (head1 != null) ? head1 : head2;
          
        return dummyHead.next;
    }
  
    // 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 order
class 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 program
llist = 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 order
using 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:  

Thanks to Gaurav Ahirwar for suggesting this method.


Article Tags :