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 order
- Merge both lists.
Diagram:

Below are the implementations of the above algorithm:
Javascript
<script>
var head;
class Node
{
constructor(val)
{
this .data = val;
this .next = null ;
}
}
function newNode(key)
{
return new Node(key);
}
function sort()
{
var Ahead = new Node(0),
Dhead = new Node(0);
splitList(Ahead, Dhead);
Ahead = Ahead.next;
Dhead = Dhead.next;
Dhead = reverseList(Dhead);
head = mergeList(Ahead, Dhead);
}
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 printList()
{
var temp = head;
while (temp != null )
{
document.write(temp.data + " " );
temp = temp.next;
}
document.write();
}
function mergeList(head1, head2)
{
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;
}
function splitList(Ahead, Dhead)
{
var ascn = Ahead;
var dscn = Dhead;
var curr = head;
while (curr != null )
{
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 ;
}
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();
</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.
Please refer complete article on Sort a linked list that is sorted alternating ascending and descending orders? for more details!