Open In App

Sort the Bitonic Doubly Linked List Using Constant Space

Last Updated : 11 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a biotonic doubly linked list. The task is to sort the given linked list. A biotonic doubly linked list is a doubly linked list that is first increasing and then decreasing. A strictly increasing or a strictly decreasing list is also a biotonic doubly linked list.

Examples:

Input:

Sort-the-biotonic-doubly-linked-list-2


Output: 3 <-> 8 <-> 14 <-> 17 <-> 20

Input:

Sort-the-biotonic-doubly-linked-list-1


Output: 1 <-> 2 <-> 4 <-> 5 <-> 6 <-> 7 <-> 10 <-> 12

Approach:

Find the first node in the list which is smaller than its previous node. Let it be current. If no such node is present then list is already sorted. Else split the list into two listsfirst starting from head node till the current’s previous node and second starting from current node till the end of the list. Reverse the second doubly linked list. Refer Reverse a Doubly Linked List post. Now merge the first and second sorted doubly linked list. Refer merge procedure Merge Sort for Doubly Linked List post. The final merged list is the required sorted doubly linked list.

C++
// C++ implementation to sort the 
// biotonic doubly linked list
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node* prev;
  	Node(int x) {
     	data = x;
      	next = nullptr;
     	prev = nullptr;
    }
};

// Function to reverse a Doubly Linked List
Node* reverse(Node* headRef) {
  
    Node* temp = nullptr;
    Node* currNode = headRef;

    // Swap next and prev for all nodes
    // of doubly linked list
    while (currNode != nullptr) {
        temp = currNode->prev;
        currNode->prev = currNode->next;
        currNode->next = temp;
        currNode = currNode->prev;
    }

    // Before changing head, check for the cases
    // like empty list and list with only one node
    if (temp != nullptr)
        headRef = temp->prev;

    return headRef;
}

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

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

    // Create a dummy node to act as the head
  	// of the merged list
    Node* dummy = new Node(0);
    Node* tail = dummy;

    while (first && second) {
      
        // Pick the smaller value
        if (first->data < second->data) {
            tail->next = first;
            first->prev = tail;
            first = first->next;
        } else {
            tail->next = second;
            second->prev = tail;
            second = second->next;
        }
        tail = tail->next;
    }

    // Append the remaining nodes of the
  	// non-empty list
    if (first) {
        tail->next = first;
        first->prev = tail;
    } else {
        tail->next = second;
        second->prev = tail;
    }

    // Adjust the head of the merged list
    Node* mergedHead = dummy->next;
    mergedHead->prev = nullptr;

    return mergedHead;
}


// Function to sort a bitonic doubly linked list
Node* sort(Node* head) {
  
    // If list is empty or if it contains a single
    // node only
    if (head == nullptr || head->next == nullptr)
        return head;

    Node* current = head->next;

    while (current != nullptr) {
      
        // If true, then 'current' is the first node
        // which is smaller than its previous node
        if (current->data < current->prev->data)
            break;

        // Move to the next node
        current = current->next;
    }

    // If true, then list is already sorted
    if (current == nullptr)
        return head;

    // Split into two lists, one starting with 'head'
    // and the other starting with 'current'
    current->prev->next = nullptr;
    current->prev = nullptr;

    // Reverse the list starting with 'current'
    current = reverse(current);

    // Merge the two lists and return the
    // final merged doubly linked list
    return merge(head, current);
}

// Function to print nodes in a given doubly
// linked list
void printList(Node* head) {
  
    while (head != nullptr) {
        cout << head->data << " ";
        head = head->next;
    }
}

int main() {
  
    // Create the doubly linked list:
    // 2<->12<->11<->1
    Node* head = new Node(2);
    head->next = new Node(12);
    head->next->prev = head;
    head->next->next = new Node(11);
    head->next->next->prev = head->next;
    head->next->next->next = new Node(1);
    head->next->next->next->prev = head->next->next;

    head = sort(head);
    printList(head);

    return 0;
}
C
// C implementation to sort the 
// biotonic doubly linked list

#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};

struct Node* createNode(int newdata);
  
// Function to reverse a Doubly Linked List
struct Node* reverse(struct Node* headRef) {
    struct Node* temp = NULL;
    struct Node* currNode = headRef;

    // Swap next and prev for all nodes
    // of doubly linked list
    while (currNode != NULL) {
        temp = currNode->prev;
        currNode->prev = currNode->next;
        currNode->next = temp;
        currNode = currNode->prev;
    }

    // Before changing head, check for the cases
    // like empty list and list with only one node
    if (temp != NULL)
        headRef = temp->prev;

    return headRef;
}

// Function to merge two sorted doubly 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;

    // Create a dummy node to act as the 
  	// head of the merged list
    struct Node* dummy = createNode(0);
    struct Node* tail = dummy;

    while (first && second) {
      
        // Pick the smaller value
        if (first->data < second->data) {
            tail->next = first;
            first->prev = tail;
            first = first->next;
        } else {
            tail->next = second;
            second->prev = tail;
            second = second->next;
        }
        tail = tail->next;
    }

    // Append the remaining nodes of the non-empty list
    if (first) {
        tail->next = first;
        first->prev = tail;
    } else {
        tail->next = second;
        second->prev = tail;
    }

    // Adjust the head of the merged list
    struct Node* mergedHead = dummy->next;
    mergedHead->prev = NULL;

    return mergedHead;
}


// Function to sort a bitonic doubly linked list
struct Node* sort(struct Node* head) {
  
    // If list is empty or if it contains a single
    // node only
    if (head == NULL || head->next == NULL)
        return head;

    struct Node* currNode = head->next;

    while (currNode != NULL) {
      
        // If true, then 'currNode' is the first node
        // which is smaller than its previous node
        if (currNode->data < currNode->prev->data)
            break;

        // Move to the next node
        currNode = currNode->next;
    }

    // If true, then list is already sorted
    if (currNode == NULL)
        return head;

    // Split into two lists, one starting with 'head'
    // and the other starting with 'currNode'
    currNode->prev->next = NULL;
    currNode->prev = NULL;

    // Reverse the list starting with 'currNode'
    currNode = reverse(currNode);

    // Merge the two lists and return the
    // final merged doubly linked list
    return merge(head, currNode);
}

// Function to print nodes in a given doubly
// linked list
void printList(struct Node* head) {

    while (head != NULL) {
        printf("%d ", head->data);
        head = head->next;
    }
}

struct Node* createNode(int newdata) {
    struct Node* newNode = 
      		(struct Node*)malloc(sizeof(struct Node));
    newNode->data = newdata;
    newNode->next = NULL;
    newNode->prev = NULL;
    return newNode;
}

int main() {
  
    // Create the doubly linked list:
    // 2<->12<->11<->1
    struct Node* head = createNode(2);
    head->next = createNode(12);
    head->next->prev = head;
    head->next->next = createNode(11);
    head->next->next->prev = head->next;
    head->next->next->next = createNode(1);
    head->next->next->next->prev = head->next->next;

    head = sort(head);
    printList(head);

    return 0;
}
Java
// Java implementation to sort the
// biotonic doubly linked list

class Node {
    int data;
    Node next;
    Node prev;

    Node(int x) {
        data = x;
        next = null;
        prev = null;
    }
}

class GfG {
  
    // Function to reverse a Doubly Linked List
    static Node reverse(Node headRef) {
        Node temp = null;
        Node currNode = headRef;

        // Swap next and prev for all nodes of doubly linked list
        while (currNode != null) {
            temp = currNode.prev;
            currNode.prev = currNode.next;
            currNode.next = temp;
            currNode = currNode.prev;
        }

        // Before changing head, check for the cases like 
      	// empty list and list with only one node
        if (temp != null)
            headRef = temp.prev;

        return headRef;
    }

    // Function to merge two sorted doubly linked lists
	static 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;

    	// Create a dummy node to act as the head 
      	// of the merged list
        Node dummy = new Node(0);
        Node tail = dummy;

        while (first != null && second != null) {
          
            // Pick the smaller value
            if (first.data < second.data) {
                tail.next = first;
                first.prev = tail;
                first = first.next;
            } else {
                tail.next = second;
                second.prev = tail;
                second = second.next;
            }
            tail = tail.next;
        }

        // Append the remaining nodes of the non-empty list
        if (first != null) {
            tail.next = first;
            first.prev = tail;
        } else {
            tail.next = second;
            second.prev = tail;
        }

        // Adjust the head of the merged list
        Node mergedHead = dummy.next;
        mergedHead.prev = null;

        return mergedHead;
    }

    // Function to sort a bitonic doubly linked list
    static Node sort(Node head) {
      
        // If list is empty or if it contains a single node only
        if (head == null || head.next == null)
            return head;

        Node currNode = head.next;

        while (currNode != null) {
          
            // If true, then 'currNode' is the first node which
          	// is smaller than its previous node
            if (currNode.data < currNode.prev.data)
                break;

            // Move to the next node
            currNode = currNode.next;
        }

        // If true, then list is already sorted
        if (currNode == null)
            return head;

        // Split into two lists, one starting with 'head'
      	// and the other starting with 'currNode'
        currNode.prev.next = null;
        currNode.prev = null;

        // Reverse the list starting with 'currNode'
        currNode = reverse(currNode);

        // Merge the two lists and return the final merged
      	// doubly linked list
        return merge(head, currNode);
    }

    static void printList(Node head) {
      
        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
      
        // Create the doubly linked list:
    	// 2<->12<->11<->1
        Node head = new Node(2);
        head.next = new Node(12);
        head.next.prev = head;
        head.next.next = new Node(11);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(1);
        head.next.next.next.prev = head.next.next;

        head = sort(head);
       	printList(head);
    }
}
Python
# Python implementation to sort the
# biotonic doubly linked list

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

# Function to reverse a Doubly Linked List
def reverse(head_ref):
    temp = None
    currNode = head_ref

    # Swap next and prev for all nodes
    # of doubly linked list
    while currNode is not None:
        temp = currNode.prev
        currNode.prev = currNode.next
        currNode.next = temp
        currNode = currNode.prev

    # Before changing head, check for the cases
    # like empty list and list with only one node
    if temp is not None:
        head_ref = temp.prev

    return head_ref

# Function to merge two sorted doubly linked lists
def merge(first, second):
  
    # If first linked list is empty
    if not first:
        return second

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

    # Create a dummy node to act as the 
    # head of the merged list
    dummy = Node(0)
    tail = dummy

    while first and second:
      
        # Pick the smaller value
        if first.data < second.data:
            tail.next = first
            first.prev = tail
            first = first.next
        else:
            tail.next = second
            second.prev = tail
            second = second.next
        tail = tail.next

    # Append the remaining nodes of the non-empty list
    if first:
        tail.next = first
        first.prev = tail
    else:
        tail.next = second
        if second:
            second.prev = tail

    # Adjust the head of the merged list
    merged_head = dummy.next
    merged_head.prev = None

    return merged_head


# Function to sort a bitonic doubly linked list
def sort(head):
  
    # If list is empty or if it contains a single
    # node only
    if head is None or head.next is None:
        return head

    currNode = head.next

    while currNode is not None:
      
        # If true, then 'currNode' is the first node
        # which is smaller than its previous node
        if currNode.data < currNode.prev.data:
            break

        # Move to the next node
        currNode = currNode.next

    # If true, then list is already sorted
    if currNode is None:
        return head

    # Split into two lists, one starting with 'head'
    # and the other starting with 'currNode'
    currNode.prev.next = None
    currNode.prev = None

    # Reverse the list starting with 'currNode'
    currNode = reverse(currNode)

    # Merge the two lists and return the
    # final merged doubly linked list
    return merge(head, currNode)

def printList(head):

    while head is not None:
        print(head.data, end=" ")
        head = head.next

if __name__ == "__main__":
  
    # Create the doubly linked list:
    # 2<->12<->11<->1
    head = Node(2)
    head.next = Node(12)
    head.next.prev = head
    head.next.next = Node(11)
    head.next.next.prev = head.next
    head.next.next.next = Node(1)
    head.next.next.next.prev = head.next.next

    head = sort(head)
    printList(head)
C#
// C# implementation to sort the
// biotonic doubly linked list

class Node {
    public int data;
    public Node next;
    public Node prev;

    public Node(int x) {
        data = x;
        next = null;
        prev = null;
    }
}

class GfG {
  
    // Function to reverse a Doubly Linked List
    static Node Reverse(Node headRef) {
        Node temp = null;
        Node currNode = headRef;

        // Swap next and prev for all nodes of 
      	// doubly linked list
        while (currNode != null) {
            temp = currNode.prev;
            currNode.prev = currNode.next;
            currNode.next = temp;
            currNode = currNode.prev;
        }

        // Before changing head, check for the cases like 
      	// empty list and list with only one node
        if (temp != null)
            headRef = temp.prev;

        return headRef;
    }

    // Function to merge two sorted doubly linked lists
    static 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;

        // Create a dummy node to act as the head
      	// of the merged list
        Node dummy = new Node(0);
        Node tail = dummy;

        while (first != null && second != null) {
          
            // Pick the smaller value
            if (first.data < second.data) {
                tail.next = first;
                first.prev = tail;
                first = first.next;
            }
            else {
              
                tail.next = second;
                second.prev = tail;
                second = second.next;
            }
            tail = tail.next;
        }

        // Append the remaining nodes of the
     	// non-empty list
        if (first != null) {
            tail.next = first;
            first.prev = tail;
        }
        else {
            tail.next = second;
            second.prev = tail;
        }

        // Adjust the head of the merged list
        Node mergedHead = dummy.next;
        mergedHead.prev = null;

        return mergedHead;
    }


    // Function to sort a bitonic doubly linked list
    static Node Sort(Node head) {
      
        // If list is empty or if it contains a 
      	// single node only
        if (head == null || head.next == null)
            return head;

        Node currNode = head.next;

        while (currNode != null) {
          
            // If true, then 'currNode' is the first node
          	// which is smaller than its previous node
            if (currNode.data < currNode.prev.data)
                break;

            // Move to the next node
            currNode = currNode.next;
        }

        // If true, then list is already sorted
        if (currNode == null)
            return head;

        // Split into two lists, one starting with 
      	// 'head' and the other starting with 'currNode'
        currNode.prev.next = null;
        currNode.prev = null;

        // Reverse the list starting with 'currNode'
        currNode = Reverse(currNode);

        // Merge the two lists and return the 
      	// final merged doubly linked list
        return Merge(head, currNode);
    }

    static void PrintList(Node head) {

        while (head != null) {
            System.Console.Write(head.data + " ");
            head = head.next;
        }
        System.Console.WriteLine();
    }

    static void Main(string[] args) {
      
        // Create the doubly linked list:
    	// 2<->12<->11<->1
        Node head = new Node(2);
        head.next = new Node(12);
        head.next.prev = head;
        head.next.next = new Node(11);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(1);
        head.next.next.next.prev = head.next.next;
      
        head = Sort(head);
        PrintList(head);
    }
}
JavaScript
// Javascript implementation to sort the
// biotonic doubly linked list    

class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

// Function to reverse a Doubly Linked List
function reverse(headRef) {
    let temp = null;
    let currNode = headRef;

    // Swap next and prev for all nodes
    // of doubly linked list
    while (currNode !== null) {
        temp = currNode.prev;
        currNode.prev = currNode.next;
        currNode.next = temp;
        currNode = currNode.prev;
    }

    // Before changing head, check for the cases
    // like empty list and list with only one node
    if (temp !== null) {
        headRef = temp.prev;
    }

    return headRef;
}

// Function to merge two sorted doubly linked lists
function merge(first, second) {

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

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

    // Create a dummy node to act as the 
    // head of the merged list
    let dummy = new Node(0);
    let tail = dummy;

    while (first && second) {
    
        // Pick the smaller value
        if (first.data < second.data) {
            tail.next = first;
            first.prev = tail;
            first = first.next;
        } else {
            tail.next = second;
            second.prev = tail;
            second = second.next;
        }
        tail = tail.next;
    }

    // Append the remaining nodes of the non-empty list
    if (first) {
        tail.next = first;
        first.prev = tail;
    } else {
        tail.next = second;
        if (second) {
            second.prev = tail;
        }
    }

    // Adjust the head of the merged list
    let mergedHead = dummy.next;
    mergedHead.prev = null;

    return mergedHead;
}


// Function to sort a bitonic doubly linked list
function sort(head) {

    // If list is empty or if it contains a single
    // node only
    if (!head || !head.next) return head;

    let currNode = head.next;

    while (currNode !== null) {
    
        // If true, then 'currNode' is the first node
        // which is smaller than its previous node
        if (currNode.data < currNode.prev.data) break;

        // Move to the next node
        currNode = currNode.next;
    }

    // If true, then list is already sorted
    if (currNode === null) return head;

    // Split into two lists, one starting with 'head'
    // and the other starting with 'currNode'
    currNode.prev.next = null;
    currNode.prev = null;

    // Reverse the list starting with 'currNode'
    currNode = reverse(currNode);

    // Merge the two lists and return the
    // final merged doubly linked list
    return merge(head, currNode);
}

// Function to print nodes in a given doubly
// linked list
function printList(head) {

    let output = '';
    while (head !== null) {
        output += head.data + ' ';
        head = head.next;
    }
    console.log(output.trim());
}

// Create the doubly linked list:
// 2<->12<->11<->1
let head = new Node(2);
head.next = new Node(12);
head.next.prev = head;
head.next.next = new Node(11);
head.next.next.prev = head.next;
head.next.next.next = new Node(1);
head.next.next.next.prev = head.next.next;

head = sort(head);
printList(head);

Output
1 2 11 12 

Time Complexity: O(n), where n is number of nodes in DLL.
Auxiliary Space: O(1)


Similar Reads