Skip to content
Related Articles

Related Articles

Reverse a Linked List according to its Size
  • Difficulty Level : Medium
  • Last Updated : 10 Jul, 2019

Given a linked list with n nodes, reverse it in the following way :

  1. If n is even, reverse it in group of n/2 nodes.
  2. If n is odd, keep the middle node as it is, reverse first n/2 elements and reverse last n/2 elements.

Examples:

Input : 1 2 3 4 5 6 (n is even)
Output : 3 2 1 6 5 4

Input : 1 2 3 4 5 6 7 (n is odd)
Output : 3 2 1 4 7 6 5

Approach: The idea is similar to Reversing a linked list in groups of size k where k is n/2. Just need to check for mid node.

  • If n is even, divide the linked list into two parts i.e. first n/2 elements and last n/2 elements and reverse both the parts.
  • If n is odd, divide the linked list into three parts i.e. first n/2 elements, (n/2 + 1) th element and last n/2 elements and reverse both the parts except (n/2 + 1) th element .

C++




// C++ program to reverse given
// linked list according to its size
#include <bits/stdc++.h>
using namespace std;
  
struct Node {
    int data;
    Node* next;
};
  
// Function to create a new Node
Node* newNode(int data)
{
    Node *temp = new Node;
    temp->data = data;
    temp->next = NULL;
    return temp;
}
  
// Prints a list.
void printList(Node* head)
{
    Node *temp = head;
    while (temp) {
        cout << temp->data << " ";
        temp = temp->next;
    }
    cout << endl;
}
  
/* Function to push a Node */
void push(Node** head_ref, int new_data)
{
    Node* new_Node = new Node;
    new_Node->data = new_data;
    new_Node->next = (*head_ref);
    (*head_ref) = new_Node;
}
  
// Returns size of list.
int getSize(Node* head)
{
    Node* curr = head;
    int count = 0;
    while (curr) {
        curr = curr->next;
        count++;
    }
    return count;
}
  
// Function to reverse the linked
// list according to its size
Node* reverseSizeBy2Util(Node* head, int k, 
                            bool skipMiddle)
{
    if (!head)
        return NULL;
  
    int count = 0;
    Node* curr = head;
    Node* prev = NULL;
    Node* next;
  
    // Reverse current block of list.
    while (curr && count < k) {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
        count++;
    }
  
    // If size is even, reverse next block too.
    if (!skipMiddle)
        head->next = reverseSizeBy2Util(next, k, false);
  
    else {
  
        // if size is odd, skip next element
        // and reverse the block after that.
        head->next = next;
        if (next)
            next->next = reverseSizeBy2Util(next->next,
                                              k, true);
    }
    return prev;
}
  
Node* reverseBySizeBy2(Node* head)
{
    // Get the size of list.
    int n = getSize(head);
  
    // If the size is even, no need
    // to skip middle Node.
    if (n % 2 == 0)
        return reverseSizeBy2Util(head, n/2, false);
  
    // If size is odd, middle Node has
    // to be skipped.
    else
        return reverseSizeBy2Util(head, n/2, true);
}
  
// Drivers code
int main()
{
    /* Start with the empty list */
    Node* head = NULL;
  
    /* Created Linked list is 1->2->3->4->5->6->7->8->9 */
    push(&head, 9);
    push(&head, 8);
    push(&head, 7);
    push(&head, 6);
    push(&head, 5);
    push(&head, 4);
    push(&head, 3);
    push(&head, 2);
    push(&head, 1);
  
    cout << "Original List : ";
    printList(head);
  
    cout << "Reversed List : ";
    Node* reversedHead = reverseBySizeBy2(head);
    printList(reversedHead);
  
    return 0;
}


Java




// Java program to reverse given 
// linked list according to its size 
class GFG
{
  
static class Node
    int data; 
    Node next; 
}; 
  
// Function to create a new Node 
static Node newNode(int data) 
    Node temp = new Node(); 
    temp.data = data; 
    temp.next = null
    return temp; 
  
// Prints a list. 
static void printList(Node head) 
    Node temp = head; 
    while (temp != null
    
        System.out.print( temp.data + " "); 
        temp = temp.next; 
    } System.out.println();
  
// Function to push a Node 
static Node push(Node head_ref, int new_data) 
    Node new_Node = new Node(); 
    new_Node.data = new_data; 
    new_Node.next = (head_ref); 
    (head_ref) = new_Node; 
    return head_ref;
  
// Returns size of list. 
static int getSize(Node head) 
    Node curr = head; 
    int count = 0
    while (curr != null)
    
        curr = curr.next; 
        count++; 
    
    return count; 
  
// Function to reverse the linked 
// list according to its size 
static Node reverseSizeBy2Util(Node head, int k, 
                            boolean skipMiddle) 
    if (head == null
        return null
  
    int count = 0
    Node curr = head; 
    Node prev = null
    Node next=null
  
    // Reverse current block of list. 
    while (curr!=null && count < k)
    
        next = curr.next; 
        curr.next = prev; 
        prev = curr; 
        curr = next; 
        count++; 
    
  
    // If size is even, reverse next block too. 
    if (!skipMiddle) 
        head.next = reverseSizeBy2Util(next, k, false); 
  
    else 
    
  
        // if size is odd, skip next element 
        // and reverse the block after that. 
        head.next = next; 
        if (next != null
            next.next = reverseSizeBy2Util(next.next, 
                                            k, true); 
    
    return prev; 
  
static Node reverseBySizeBy2(Node head) 
    // Get the size of list. 
    int n = getSize(head); 
  
    // If the size is even, no need 
    // to skip middle Node. 
    if (n % 2 == 0
        return reverseSizeBy2Util(head, n/2, false); 
  
    // If size is odd, middle Node has 
    // to be skipped. 
    else
        return reverseSizeBy2Util(head, n/2, true); 
  
// Driver code 
public static void main(String args[]) 
    // Start with the empty list /
    Node head = null
  
    // Created Linked list is 1.2.3.4.5.6.7.8.9 /
    head = push(head, 9); 
    head = push(head, 8); 
    head = push(head, 7); 
    head = push(head, 6); 
    head = push(head, 5); 
    head = push(head, 4); 
    head = push(head, 3); 
    head = push(head, 2); 
    head = push(head, 1); 
  
    System.out.print( "Original List : "); 
    printList(head); 
  
    System.out.print( "Reversed List : "); 
    Node reversedHead = reverseBySizeBy2(head); 
    printList(reversedHead); 
}
}
  
// This code is contributed by Arnab Kundu 


Python3




# Python3 program to reverse given 
# linked list according to its size 
  
class Node:
      
    def __init__(self, data):
        self.data = data
        self.next = None
  
# Prints a list. 
def printList(head): 
   
    temp = head 
    while temp:  
        print(temp.data, end = " "
        temp = temp.next 
       
    print()
  
# Function to push a Node 
def push(head_ref, new_data): 
   
    new_Node = Node(new_data) 
    new_Node.next = head_ref 
    head_ref = new_Node
      
    return head_ref
  
# Returns size of list. 
def getSize(head):
   
    curr = head 
    count = 0 
    while curr:  
        curr = curr.next 
        count += 1 
       
    return count 
   
# Function to reverse the linked 
# list according to its size 
def reverseSizeBy2Util(head, k, skipMiddle): 
   
    if not head:
        return None 
  
    count = 0 
    curr, prev, next = head, None, None 
      
    # Reverse current block of list. 
    while curr and count < k:
        next = curr.next 
        curr.next = prev 
        prev = curr 
        curr = next 
        count += 1 
       
    # If size is even, reverse next block too. 
    if not skipMiddle: 
        head.next = reverseSizeBy2Util(next, k, False
  
    else:
  
        # if size is odd, skip next element 
        # and reverse the block after that. 
        head.next = next 
        if next
            next.next = reverseSizeBy2Util(next.next
                                            k, True
       
    return prev 
   
def reverseBySizeBy2(head): 
   
    # Get the size of list. 
    n = getSize(head) 
  
    # If the size is even, no 
    # need to skip middle Node. 
    if n % 2 == 0
        return reverseSizeBy2Util(head, n//2, False
  
    # If size is odd, middle 
    # Node has to be skipped. 
    else:
        return reverseSizeBy2Util(head, n//2, True
   
# Drivers code 
if __name__ == "__main__"
   
    # Start with the empty list 
    head = None 
  
    # Created Linked list is 1.2.3.4.5.6.7.8.9 
    head = push(head, 9
    head = push(head, 8
    head = push(head, 7
    head = push(head, 6
    head = push(head, 5
    head = push(head, 4
    head = push(head, 3
    head = push(head, 2
    head = push(head, 1
  
    print("Original List : ", end = "") 
    printList(head) 
  
    print("Reversed List : ", end = "")
    reversedHead = reverseBySizeBy2(head) 
    printList(reversedHead) 
   
# This code is contributed by Rituraj Jain


C#




// C# program to reverse given 
// linked list according to its size 
using System;
      
class GFG
{
  
public class Node
    public int data; 
    public Node next; 
}; 
  
// Function to create a new Node 
static Node newNode(int data) 
    Node temp = new Node(); 
    temp.data = data; 
    temp.next = null
    return temp; 
  
// Prints a list. 
static void printList(Node head) 
    Node temp = head; 
    while (temp != null
    
        Console.Write( temp.data + " "); 
        temp = temp.next; 
    } Console.WriteLine();
  
// Function to push a Node 
static Node push(Node head_ref, int new_data) 
    Node new_Node = new Node(); 
    new_Node.data = new_data; 
    new_Node.next = (head_ref); 
    (head_ref) = new_Node; 
    return head_ref;
  
// Returns size of list. 
static int getSize(Node head) 
    Node curr = head; 
    int count = 0; 
    while (curr != null)
    
        curr = curr.next; 
        count++; 
    
    return count; 
  
// Function to reverse the linked 
// list according to its size 
static Node reverseSizeBy2Util(Node head, int k, 
                            Boolean skipMiddle) 
    if (head == null
        return null
  
    int count = 0; 
    Node curr = head; 
    Node prev = null
    Node next=null
  
    // Reverse current block of list. 
    while (curr!=null && count < k)
    
        next = curr.next; 
        curr.next = prev; 
        prev = curr; 
        curr = next; 
        count++; 
    
  
    // If size is even, reverse next block too. 
    if (!skipMiddle) 
        head.next = reverseSizeBy2Util(next, k, false); 
  
    else
    
  
        // if size is odd, skip next element 
        // and reverse the block after that. 
        head.next = next; 
        if (next != null
            next.next = reverseSizeBy2Util(next.next, 
                                            k, true); 
    
    return prev; 
  
static Node reverseBySizeBy2(Node head) 
    // Get the size of list. 
    int n = getSize(head); 
  
    // If the size is even, no need 
    // to skip middle Node. 
    if (n % 2 == 0) 
        return reverseSizeBy2Util(head, n/2, false); 
  
    // If size is odd, middle Node has 
    // to be skipped. 
    else
        return reverseSizeBy2Util(head, n/2, true); 
  
// Driver code 
public static void Main(String []args) 
    // Start with the empty list /
    Node head = null
  
    // Created Linked list is 1.2.3.4.5.6.7.8.9 /
    head = push(head, 9); 
    head = push(head, 8); 
    head = push(head, 7); 
    head = push(head, 6); 
    head = push(head, 5); 
    head = push(head, 4); 
    head = push(head, 3); 
    head = push(head, 2); 
    head = push(head, 1); 
  
    Console.Write( "Original List : "); 
    printList(head); 
  
    Console.Write( "Reversed List : "); 
    Node reversedHead = reverseBySizeBy2(head); 
    printList(reversedHead); 
}
}
  
// This code is contributed by Rajput-Ji


Output:

Original List : 1 2 3 4 5 6 7 8 9 
Reversed List : 4 3 2 1 5 9 8 7 6

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :