# Alternate sorting of Linked list

• Difficulty Level : Hard
• Last Updated : 04 Oct, 2018

Given a linked list containing n nodes. The problem is to rearrange the nodes of the list in such a way that the data in first node is first minimum, second node is first maximum, third node is second minimum, fourth node is second maximum and so on.

Examples:

```Input : list: 4->1->3->5->2
Output : 1->5->2->4->3

Input : list: 10->9->8->7->6->5
Output : 5->10->6->9->7->8
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: Following are the steps:

1. Sort the linked list using Merge Sort technique.
2. Split the list into front and back lists. Refer FrontBackProcedure of this post.
3. Now, reverse the back list. Refer this post.
4. Finally, merge the nodes of first and back lists in alternate order.
 `// C++ implementation of alternative sorting``// of the Linked list``#include `` ` `using` `namespace` `std;`` ` `// node of a linked list``struct` `Node {``    ``int` `data;``    ``struct` `Node* next;``};`` ` `// function to get a new node``Node* getNode(``int` `data)``{``    ``// allocate space for node``    ``Node* newNode = (Node*)``malloc``(``sizeof``(Node));`` ` `    ``// put in the data``    ``newNode->data = data;``    ``newNode->next = NULL;`` ` `    ``return` `newNode;``}`` ` `// Split the nodes of the given list into front and ``// back halves, and return the two lists using the ``// reference parameters. If the length is odd, the ``// extra node should go in the front list. Uses the ``// fast/slow pointer strategy.``void` `FrontBackSplit(Node* source,``                    ``Node** frontRef, Node** backRef)``{``    ``Node* fast;``    ``Node* slow;``    ``if` `(source == NULL || source->next == NULL) {``        ``// length < 2 cases``        ``*frontRef = source;``        ``*backRef = NULL;``    ``}``    ``else` `{``        ``slow = source;``        ``fast = source->next;`` ` `        ``// Advance 'fast' two nodes, and``        ``// advance 'slow' one node``        ``while` `(fast != NULL) {``            ``fast = fast->next;``            ``if` `(fast != NULL) {``                ``slow = slow->next;``                ``fast = fast->next;``            ``}``        ``}`` ` `        ``// 'slow' is before the midpoint in the list,``        ``// so split it in two at that point.``        ``*frontRef = source;``        ``*backRef = slow->next;``        ``slow->next = NULL;``    ``}``}`` ` `// function to merge two sorted lists in``// sorted order``Node* SortedMerge(Node* a, Node* b)``{``    ``Node* result = NULL;`` ` `    ``// Base cases``    ``if` `(a == NULL)``        ``return` `b;``    ``else` `if` `(b == NULL)``        ``return` `a;`` ` `    ``// Pick either a or b, and recur``    ``if` `(a->data <= b->data) {``        ``result = a;``        ``result->next = SortedMerge(a->next, b);``    ``}``    ``else` `{``        ``result = b;``        ``result->next = SortedMerge(a, b->next);``    ``}`` ` `    ``return` `result;``}`` ` `// sorts the linked list by changing``// next pointers (not data)``void` `MergeSort(Node** headRef)``{``    ``Node* head = *headRef;``    ``Node *a, *b;`` ` `    ``// Base case -- length 0 or 1``    ``if` `((head == NULL) || (head->next == NULL))``        ``return``;`` ` `    ``// Split head into 'a' and 'b' sublists``    ``FrontBackSplit(head, &a, &b);`` ` `    ``// Recursively sort the sublists``    ``MergeSort(&a);``    ``MergeSort(&b);`` ` `    ``// merge the two sorted lists together``    ``*headRef = SortedMerge(a, b);``}`` ` `// function to reverse the linked list``static` `void` `reverse(Node** head_ref)``{``    ``Node* prev = NULL;``    ``Node* current = *head_ref;``    ``Node* next;`` ` `    ``while` `(current != NULL) {``        ``next = current->next;``        ``current->next = prev;``        ``prev = current;``        ``current = next;``    ``}`` ` `    ``*head_ref = prev;``}`` ` `// function to alternately merge two lists``void` `alternateMerge(Node* head1, Node* head2)``{``    ``Node *p, *q;``    ``while` `(head1 != NULL && head2 != NULL) {`` ` `        ``// merging nodes alternately by``        ``// making the desired links``        ``p = head1->next;``        ``head1->next = head2;``        ``head1 = p;``        ``q = head2->next;``        ``head2->next = head1;``        ``head2 = q;``    ``}``}`` ` `// function for alternative sort of the``// linked list``Node* altSortForLinkedList(Node* head)``{``    ``// sort the linked list``    ``MergeSort(&head);`` ` `    ``Node *front, *back;`` ` `    ``// Split head into 'front' and 'back' sublists``    ``FrontBackSplit(head, &front, &back);`` ` `    ``// reversing the 'back' list``    ``reverse(&back);`` ` `    ``// merging the nodes of 'front' and 'back'``    ``// lists alternately``    ``alternateMerge(front, back);`` ` `    ``// required head of final list``    ``return` `front;``}`` ` `// Function to print nodes in``// a given linked list``void` `printList(Node* head)``{``    ``while` `(head != NULL) {``        ``cout << head->data << ``" "``;``        ``head = head->next;``    ``}``}`` ` `// Driver program to test above``int` `main()``{``    ``// linked list: 10->9->8->7->6->5``    ``Node* head = getNode(10);``    ``head->next = getNode(9);``    ``head->next->next = getNode(8);``    ``head->next->next->next = getNode(7);``    ``head->next->next->next->next = getNode(6);``    ``head->next->next->next->next->next = getNode(5);`` ` `    ``cout << ``"Original list: "``;``    ``printList(head);`` ` `    ``head = altSortForLinkedList(head);`` ` `    ``cout << ``"\nModified list: "``;``    ``printList(head);`` ` `    ``return` `0;``}`

Output:

```Original list: 10 9 8 7 6 5
Modified list: 5 10 6 9 7 8
```

Time Complexity: O(n*logn).

My Personal Notes arrow_drop_up