Open In App

Rearrange a given linked list in-place

Last Updated : 04 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a singly linked list L0 -> L1 -> … -> Ln-1 -> Ln. Rearrange the nodes in the list so that the newly formed list is : L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 ... You are required to do this in place without altering the nodes' values. 

Examples: 

Input: 1 -> 2 -> 3 -> 4
Output: 1 -> 4 -> 2 -> 3
Explanation: Here n = 4, so the correct order is L0->L3->L1->L2

Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 5 -> 2 -> 4 -> 3
Explanation: Here n = 4, so the correct order is L0->L4->L1->L3->L2

[Naive Approach] Using two nested loops- O(n^2) Time and O(1) Space

The idea is to start traversing from head node. For each node, perform the following operations:

  • Traverse the list to find the last node.
  • Disconnect the last node from the list.
  • Place the removed last node after the current node.
  • Update current to its next node.

[Efficient Approach] By Reversing Second Half - O(n) Time and O(1) Space

  • Find the middle of the linked list using the fast and slow pointer method. This involves moving one pointer twice as fast as the other so that when the faster pointer reaches the end, the slower pointer will be at the middle.
  • Reverse the second half of the list starting just after the middle node and split them in two parts.
  • Merge the two halves together by alternating nodes from the first half with nodes from the reversed second half.

Below is the implementation of the above approach :

C++
// C++ code to rearrange a given linked list in-place
#include <bits/stdc++.h>
using namespace std;

class Node {
  public:
    int data;
    Node *next;

    Node(int x) {
        data = x;
        next = NULL;
    }
};

Node *reverselist(Node *head) {
    Node *prev = nullptr, *curr = head, *next;

    while (curr) {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

void printList(Node *curr) {
  
    while (curr != nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
}

// Function to rearrange a linked list
Node *rearrange(Node *head) {
  
    // Find the middle point using tortoise and hare method
    Node *slow = head, *fast = slow->next;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
  
    // Split the linked list into two halves
    Node *head1 = head;
    Node *head2 = slow->next;
    slow->next = NULL;
    
  	// Reverse the second half
    head2 = reverselist(head2);
    
  	// Merge alternate nodes
    head = new Node(0); 
    Node *curr = head;
    while (head1 || head2) {
      
        // First add the element from the first list
        if (head1) {
            curr->next = head1;
            curr = curr->next;
            head1 = head1->next;
        }
      
        // Then add the element from the second list
        if (head2) {
            curr->next = head2;
            curr = curr->next;
            head2 = head2->next;
        }
    }
  
    // Return the head of the new list
    return head->next;
}


int main() {
  
 	// singly linked list 1->2->3->4->5
    Node *head = new Node(1);
    head->next = new Node(2);
    head->next->next = new Node(3);
    head->next->next->next = new Node(4);
    head->next->next->next->next = new Node(5); 
  	
    head = rearrange(head); 
    printList(head);        
    return 0;
}
C
// C code to rearrange a given linked list in-place

#include <stdio.h>
#include <stdlib.h>

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


struct Node *reverselist(struct Node *head) {
  
    // Initialize prev and current pointers
    struct Node *prev = NULL, *curr = head, *next;
    while (curr) {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

void printList(struct Node *curr) {
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
}

// Function to rearrange a linked list
struct Node *rearrange(struct Node *head) {
  
    // Find the middle point using tortoise 
  	// and hare method
    struct Node *slow = head, *fast = slow->next;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    
    // Split the linked list into two halves
    // head1, head of first half
    // head2, head of second half
    struct Node *head1 = head;
    struct Node *head2 = slow->next;
    slow->next = NULL;
    
    // Reverse the second half
    head2 = reverselist(head2);
    
    // Merge alternate nodes
    struct Node dummy; 
    struct Node *curr = &dummy;
    dummy.next = NULL;
    
    while (head1 || head2) {
      
        // First add the element from head1
        if (head1) {
            curr->next = head1;
            curr = curr->next;
            head1 = head1->next;
        }
      
        // Then add the element from head2
        if (head2) {
            curr->next = head2;
            curr = curr->next;
            head2 = head2->next;
        }
    }
  
    return dummy.next;
}


struct Node *newNode(int key) {
    struct Node *temp = 
      (struct Node *)malloc(sizeof(struct Node));
    temp->data = key;
    temp->next = NULL;
    return temp;
}

int main() {
  
 	// singly linked list 1->2->3->4->5
    struct Node *head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(5);

    head = rearrange(head);
  
    printList(head);        
    return 0;
}
Java
// Java code to rearrange a given linked list in-place
class Node {
    int data;
    Node next;

    Node(int d) {
        data = d;
        next = null;
    }
}

class GfG {

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

     static Node reverseList(Node node) {
        Node prev = null, curr = node, next;
        while (curr != null) {
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }

    // Method to rearrange the linked list
    static Node rearrange(Node node) {
      
        // Check if the list is empty or has only one node
        if (node == null || node.next == null) {
            return node;
        }

        // Find the middle point using tortoise and hare
        // method
        Node slow = node, fast = node.next;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        // Split the linked list into two halves
        Node firstHalf = node;
        Node secondHalf = slow.next;
        slow.next = null;

        // Reverse the second half of the list
        secondHalf = reverseList(secondHalf);

        // Merge alternate nodes from the two halves
        Node dummy = new Node(0);
        Node curr = dummy;
        while (firstHalf != null || secondHalf != null) {
            if (firstHalf != null) {
                curr.next = firstHalf;
                curr = curr.next;
                firstHalf = firstHalf.next;
            }
            if (secondHalf != null) {
                curr.next = secondHalf;
                curr = curr.next;
                secondHalf = secondHalf.next;
            }
        }

        // Return the new head of the rearranged list
        return dummy.next;
    }

    public static void main(String[] args){

        // singly linked list 1->2->3->4->5
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);

        head = rearrange(head);
        printList(head);
    }
}
Python
# Python program to rearrange link list in place

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


def printlist(node):
    
    if node is None:
        return
    
    while node is not None:
        print(node.data, end=" ")
        node = node.next

def reverselist(node):
    
    prev = None
    curr = node
    next = None
    
    while curr is not None:
        next = curr.next
        curr.next = prev
        prev = curr
        curr = next
    
    node = prev
    return node


def rearrange(node):
    
    # Find the middle point using the 
    # tortoise and hare method
    slow = node
    fast = slow.next
    
    while fast is not None and fast.next is not None:
        slow = slow.next
        fast = fast.next.next

    # Split the linked list into two halves
    node1 = node
    node2 = slow.next
    slow.next = None

    # Reverse the second half
    node2 = reverselist(node2)

    # Merge alternate nodes
    node = Node(0)  
    curr = node
    
    while node1 is not None or node2 is not None:

        # Add the element from the first list
        if node1 is not None:
            curr.next = node1
            curr = curr.next
            node1 = node1.next

        # Add the element from the second list
        if node2 is not None:
            curr.next = node2
            curr = curr.next
            node2 = node2.next

    # Return the head of the rearranged list
    return node.next

# singly linked list 1->2->3->4->5
head = None
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)

head = rearrange(head)
printlist(head)
C#
// C# program to rearrange link list in place
using System;

public class Node {
    public int Data;
    public Node Next;

    public Node(int data) {
        Data = data;
        Next = null;
    }
}

class GfG {
  
    static void PrintList(Node node) {
        if (node == null) {
            Console.WriteLine("List is empty.");
            return;
        }

        while (node != null) {
             Console.Write(node.Data + " ");
            node = node.Next;
        }
    }

    static Node ReverseList(Node node) {
        Node prev = null;
        Node curr = node;
        Node next = null;

        while (curr != null) {
            next = curr.Next;
            curr.Next = prev;
            prev = curr;
            curr = next;
        }

        return prev;
    }

    // Method to rearrange the linked list in-place and
    // return the new head
    static Node Rearrange(Node node) {
        if (node == null || node.Next == null)
            return node;

        // Find the middle point using tortoise and hare
        // method
        Node slow = node;
        Node fast = node.Next;

        while (fast != null && fast.Next != null) {
            slow = slow.Next;
            fast = fast.Next.Next;
        }

        // Split the linked list into two halves
        Node firstHalf = node;
        Node secondHalf = slow.Next;
        slow.Next = null;

        // Reverse the second half
        secondHalf = ReverseList(secondHalf);

        // Merge alternate nodes
        Node dummy = new Node(0);
        Node curr = dummy;

        while (firstHalf != null || secondHalf != null) {
            if (firstHalf != null) {
                curr.Next = firstHalf;
                curr = curr.Next;
                firstHalf = firstHalf.Next;
            }

            if (secondHalf != null) {
                curr.Next = secondHalf;
                curr = curr.Next;
                secondHalf = secondHalf.Next;
            }
        }

        // Return the new head of the list
        return dummy.Next;
    }

    public static void Main(string[] args) {
      
       	//singly linked list 1->2->3->4->5
        Node head = new Node(1);
        head.Next = new Node(2);
        head.Next.Next = new Node(3);
        head.Next.Next.Next = new Node(4);
        head.Next.Next.Next.Next = new Node(5);
      
        head = Rearrange(head);
        PrintList(head);
    }
}
JavaScript
// Javascript program to rearrange link list in place
class Node {
    constructor(d) {
        this.data = d;
        this.next = null;
    }
}

function printList(node) {
    let result = "";
    while (node != null) {
        result += node.data + " ";
        node = node.next;
    }
    console.log(result);
}

function reverseList(node) {
    let prev = null, curr = node, next;
    while (curr != null) {
        next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

// Function to rearrange the linked list
function rearrange(head) {
    if (head == null || head.next == null) {
        return head;
    }

    // Find the middle point using 
    // tortoise and hare method
    let slow = head, fast = slow.next;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }

    // Split the linked list into two halves
    let node1 = head;
    let node2 = slow.next;
    slow.next = null;

    // Reverse the second half
    node2 = reverseList(node2);

    // Merge alternate nodes
    let dummy = new Node(0);
    let curr = dummy;
    while (node1 != null || node2 != null) {
        if (node1 != null) {
            curr.next = node1;
            curr = curr.next;
            node1 = node1.next;
        }

        if (node2 != null) {
            curr.next = node2;
            curr = curr.next;
            node2 = node2.next;
        }
    }

    return dummy.next;
}

// singly linked list 1->2->3->4->5
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);

head = rearrange(head);

printList(head);

Output
1 5 2 4 3 

Time Complexity: O(n) , where n are the number of nodes in linked list.
Auxiliary Space: O(1)


Next Article
Article Tags :
Practice Tags :

Similar Reads