Reverse a Linked List according to its Size

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

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


My Personal Notes arrow_drop_up

A Coding Enthusiast Rails Developer

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.





Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.