Merge Sort for Doubly Linked List

Given a doubly linked list, write a function to sort the doubly linked list in increasing order using merge sort.

For example, the following doubly linked list should be changed to 2<->4<->8<->10

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Merge sort for singly linked list is already discussed. The important change here is to modify the previous pointers also when merging two lists.

Below is the implementation of merge sort for doubly linked list.

C

```// C program for merge sort on doubly linked list
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next, *prev;
};

// Function to merge two linked lists
struct Node *merge(struct Node *first, struct Node *second)
{
// If first linked list is empty
if (!first)
return second;

// If second linked list is empty
if (!second)
return first;

// Pick the smaller value
if (first->data < second->data)
{
first->next = merge(first->next,second);
first->next->prev = first;
first->prev = NULL;
return first;
}
else
{
second->next = merge(first,second->next);
second->next->prev = second;
second->prev = NULL;
return second;
}
}

// Function to do merge sort
{

// Recur for left and right halves
second = mergeSort(second);

// Merge the two sorted halves
}

// A utility function to insert a new node at the
// beginning of doubly linked list
void insert(struct Node **head, int data)
{
struct Node *temp =
(struct Node *)malloc(sizeof(struct Node));
temp->data = data;
temp->next = temp->prev = NULL;
else
{
}
}

// A utility function to print a doubly linked list in
// both forward and backward directions
{
printf("Forward Traversal using next poitner\n");
{
}
printf("\nBackward Traversal using prev pointer\n");
while (temp)
{
printf("%d ", temp->data);
temp = temp->prev;
}
}

// Utility function to swap two integers
void swap(int *A, int *B)
{
int temp = *A;
*A = *B;
*B = temp;
}

// Split a doubly linked list (DLL) into 2 DLLs of
// half sizes
{
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
struct Node *temp = slow->next;
slow->next = NULL;
return temp;
}

// Driver program
int main(void)
{
return 0;
}```

Java

```// Java program to implement merge sort in singly linked list

/* Node Class */
static class Node {

int data;
Node next, prev;

// Constructor to create a new node
Node(int d) {
data = d;
next = prev = null;
}
}

void print(Node node) {
Node temp = node;
System.out.println("Forward Traversal using next pointer");
while (node != null) {
System.out.print(node.data + " ");
temp = node;
node = node.next;
}
System.out.println("\nBackward Traversal using prev pointer");
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.prev;
}
}

// Split a doubly linked list (DLL) into 2 DLLs of
// half sizes
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
Node temp = slow.next;
slow.next = null;
return temp;
}

Node mergeSort(Node node) {
if (node == null || node.next == null) {
return node;
}
Node second = split(node);

// Recur for left and right halves
node = mergeSort(node);
second = mergeSort(second);

// Merge the two sorted halves
return merge(node, second);
}

// Function to merge two linked lists
Node merge(Node first, Node second) {
// If first linked list is empty
if (first == null) {
return second;
}

// If second linked list is empty
if (second == null) {
return first;
}

// Pick the smaller value
if (first.data < second.data) {
first.next = merge(first.next, second);
first.next.prev = first;
first.prev = null;
return first;
} else {
second.next = merge(first, second.next);
second.next.prev = second;
second.prev = null;
return second;
}
}

// Driver program to test above functions
public static void main(String[] args) {

Node node = null;
list.print(node);

}
}

// This code has been contributed by Mayank Jaiswal

```

Python

```
# Program for merge sort on doubly linked list

# A node of the doublly linked list
class Node:

# Constructor to create a new node
def __init__(self, data):
self.data = data
self.next = None
self.prev = None

# Constructor for empty Doubly Linked List
def __init__(self):

# Function to merge two linked list
def merge(self, first, second):

# If first linked list is empty
if first is None:
return second

# If secon linked list is empty
if second is None:
return first

# Pick the smaller value
if first.data < second.data:
first.next = self.merge(first.next, second)
first.next.prev = first
first.prev = None
return first
else:
second.next = self.merge(first, second.next)
second.next.prev = second
second.prev = None
return second

# Function to do merge sort

# Recur for left and righ halves
second = self.mergeSort(second)

# Merge the two sorted halves

# Split the doubly linked list (DLL) into two DLLs
# of half sizes
while(True):
if fast.next is None:
break
if fast.next.next is None:
break
fast = fast.next.next
slow = slow.next

temp = slow.next
slow.next = None
return temp

# Given a reference to the head of a list and an
# integer,inserts a new node on the front of list
def push(self, new_data):

# 1. Allocates node
# 2. Put the data in it
new_node = Node(new_data)

# 3. Make next of new node as head and
# previous as None (already None)

# 4. change prev of head node to new_node

# 5. move the head to point to the new node

def printList(self, node):
temp = node
print "Forward Traversal using next poitner"
while(node is not None):
print node.data,
temp = node
node = node.next
print "\nBackward Traversal using prev pointer"
while(temp):
print temp.data,
temp = temp.prev

# Driver program to test the above functions
dll.push(5)
dll.push(20);
dll.push(4);
dll.push(3);
dll.push(30)
dll.push(10);

# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

```

Output:
```Linked List after sorting
Forward Traversal using next pointer
3 4 5 10 20 30
Backward Traversal using prev pointer
30 20 10 5 4 3```

Thanks to Goku for providing above implementation in a comment here.

Time Complexity: Time complexity of the above implementation is same as time complexity of MergeSort for arrays. It takes Θ(nLogn) time.

You may also like to see QuickSort for doubly linked list

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
3.2 Average Difficulty : 3.2/5.0
Based on 52 vote(s)