Reverse Alternate K Nodes in a Singly Linked List in C++

C++Server Side ProgrammingProgramming

In this tutorial, we are given a linked list A of length N and an integer K. We have to reverse alternate pairs of nodes with the size of each pair as K. It is also given that N is divisible by K. First argument is the head pointer of the linked list A and the second argument is an integer K, for example

Input

5 -> 6 -> 2 -> 8 -> 5 -> 2 -> 4 -> 8 -> 9 -> 6 -> null K=2

Output

6 -> 5 -> 2 -> 8 -> 2 -> 5 -> 4 -> 8 -> 6 -> 9 -> null

Input

1 -> 2 -> 5 -> 8 -> 9 -> 6 -> 4 -> 5 -> 8 -> null K=3

Output

5 -> 2 -> 1 -> 8 -> 9 -> 6 -> 8 -> 5 -> 4 -> null

Approach to Find the Solution

Iterative Solution

  • Traverse 2K nodes per iteration (or loop) and record the head and tail of each pair of K nodes in the given input (Linked list) using the join and tail pointer.

  • Then, reverse the k nodes of the linked list and join the tail node of the reversed list, with the head node of the initial linked list, pointed by the join pointer.

  • Then we will change the current pointer to the next k nodes.

  • The tail of the normal list now serves as the last node (which is pointed by the new tail), and the join pointer will point to the head of the new (reversed) list, and they are merged. We’ll iterate these steps till all the nodes follow the same steps.

Example

#include <bits/stdc++.h>
using namespace std;
class Node {
   public:
   int data;
   Node* next;
};
Node* kAltReverse(struct Node* head, int k){
   Node* prev = NULL;
   Node* curr = head;
   Node* temp = NULL;
   Node* tail = NULL;
   Node* newHead = NULL;
   Node* join = NULL;
   int t = 0;
   while (curr) {
      t = k;
      join = curr;
      prev = NULL;
      while (curr && t--) {
         temp = curr->next;
         curr->next = prev;
         prev = curr;
         curr = temp;
      }
      if (!newHead)
         newHead = prev;
      if (tail)
         tail->next = prev;
      tail = join;
      tail->next = curr;
      t = k;
      while (curr && t--) {
         prev = curr;
         curr = curr->next;
      }
      tail = prev;
   }
   return newHead;
}
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;
}
void printList(Node* node){
   int count = 0;
   while (node != NULL) {
      cout << node->data << " ";
      node = node->next;
      count++;
   }
}
int main(void){
   Node* head = NULL;
   int i;
   for (i = 6; i <27; i+=3)
      push(&head, i);
   int k = 3;
   cout << "Given linked list \n";
   printList(head);
   head = kAltReverse(head, k);
   cout << "\n Modified Linked list \n";
   printList(head);
   return (0);
}

Output

Given linked list
24 21 18 15 12 9 6
Modified Linked list
18 21 24 15 12 9 6

Recursive Solution

  • Traverse K nodes from starting and set the temp value to the k+1th node

  • Reverse all the K nodes traversed.

  • Set the next pointer of the last node of that pair of K nodes to temp.

  • Skip the next iteration in which the pair of those K nodes need to skip.

  • Recursively follow all these steps for reversing the next k nodes until the last node is reached.

Pseudo Code

reverseAltK(head, k)
   curr = head
   prev = null
   next = null
   count = 0
   WHILE count < k AND curr
      next = curr.next
      curr.next = prev
      prev = curr
      curr = next
      count = count + 1
IF head
   head.next = curr
count = 0
WHILE count < k-1 AND curr
   curr = curr.next
   count = count + 1
IF curr
   curr.next = reverseKGroupAltRecursive(curr.next, k)
return prev

Example

#include <bits/stdc++.h>
using namespace std;
/* Link list node */
class node{
   public:
   int data;
   node* next;
};
/* Helper function for kAltReverse() */
node * _kAltReverse(node *node, int k, bool b);

/* Alternatively reverses the given linked list
in groups of given size k. */
node *kAltReverse(node *head, int k){
   return _kAltReverse(head, k, true);
}
/* Helper function for kAltReverse().
It reverses k nodes of the list only if
the third parameter b is passed as true,
otherwise moves the pointer k nodes ahead
and recursively calls iteself */
node * _kAltReverse(node *Node, int k, bool b){
   if(Node == NULL)
      return NULL;
   int count = 1;
   node *prev = NULL;
   node *current = Node;
   node *next;
   /* The loop serves two purposes
      1) If b is true,
      then it reverses the k nodes
      2) If b is false,
      then it moves the current pointer */
   while(current != NULL && count <= k){
      next = current->next;
      /* Reverse the nodes only if b is true*/
         if(b == true)
            current->next = prev;
      prev = current;
      current = next;
      count++;
   }
   /* 3) If b is true, then node is the kth node.
   So attach rest of the list after node.
   4) After attaching, return the new head */
   if(b == true){
      Node->next = _kAltReverse(current, k, !b);
      return prev;
   }
   /* If b is not true, then attach
   rest of the list after prev.
   So attach rest of the list after prev */
   else{
      prev->next = _kAltReverse(current, k, !b);
      return Node;
   }
}
/* UTILITY FUNCTIONS */
/* Function to push a node */
void push(node** head_ref, int new_data){
   /* allocate node */
   node* new_node = new node();
   /* put in the data */
   new_node->data = new_data;
   /* link the old list off the new node */
   new_node->next = (*head_ref);
   /* move the head to point to the new node */
   (*head_ref) = new_node;
}
/* Function to print linked list */
void printList(node *node){
   int count = 0;
   while(node != NULL){
      cout << node->data << " ";
      node = node->next;
      count++;
   }
}
// Driver Code
int main(void){
   /* Start with the empty list */
   node* head = NULL;
   int i;
   // create a list 1->2->3->4->5...... ->20
   for(i = 20; i > 0; i--)
      push(&head, i);
   cout << "Given linked list \n";
   printList(head);
   head = kAltReverse(head, 3);
   cout << "\nModified Linked list \n";
   printList(head);
   return(0);
}

Output

Given linked list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Modified Linked list
3 2 1 4 5 6 9 8 7 10 11 12 15 14 13 16 17 18 20 19

Conclusion

This tutorial taught us how to reverse alternate k nodes in a singly linked list and pseudo-code implementation in c++ code. We can also write this code in java, python, and other languages. In this approach, we used recursion to reverse alternate K nodes and skip the remaining nodes. We hope you find this tutorial helpful.

raja
Updated on 07-Mar-2022 07:02:41

Advertisements