C++ Program For Rearranging A Given Linked List In-Place
Last Updated :
27 Jul, 2023
Given a singly linked list L0 -> L1 -> … -> Ln-1 -> Ln. Rearrange the nodes in the list so that the new 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
Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 5 -> 2 -> 4 -> 3
Simple Solution:
1) Initialize current node as head.
2) While next of current node is not null, do following
a) Find the last node, remove it from the end and insert it as next
of the current node.
b) Move current to next to next of current
The time complexity of the above simple solution is O(n2) where n is the number of nodes in the linked list.
Better Solution:
1) Copy contents of the given linked list to a vector.
2) Rearrange the given vector by swapping nodes from both ends.
3) Copy the modified vector back to the linked list.
Implementation of this approach: https://ide.geeksforgeeks.org/1eGSEy
Thanks to Arushi Dhamija for suggesting this approach.
Efficient Solution:
1) Find the middle point using tortoise and hare method.
2) Split the linked list into two halves using found middle point in step 1.
3) Reverse the second half.
4) Do alternate merge of first and second halves.
The Time Complexity of this solution is O(n).
Below is the implementation of this method.
C++
// C++ program to rearrange a
// linked list in-place
#include <bits/stdc++.h>
using namespace std;
// Linkedlist Node structure
struct Node
{
int data;
struct Node* next;
};
// Function to create newNode
// in a linkedlist
Node* newNode(int key)
{
Node* temp = new Node;
temp->data = key;
temp->next = NULL;
return temp;
}
// Function to reverse the
// linked list
void reverselist(Node** head)
{
// Initialize prev and current
// pointers
Node *prev = NULL,
*curr = *head, *next;
while (curr)
{
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
*head = prev;
}
// Function to print the
// linked list
void printlist(Node* head)
{
while (head != NULL)
{
cout << head->data << " ";
if (head->next)
cout << "-> ";
head = head->next;
}
cout << endl;
}
// Function to rearrange a
// linked list
void rearrange(Node** head)
{
// 1) 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;
}
// 2) Split the linked list in
// two halves
// head1, head of first half- 1 -> 2
// head2, head of second half- 3 -> 4
Node* head1 = *head;
Node* head2 = slow->next;
slow->next = NULL;
// 3) Reverse the second half,
// i.e., 4 -> 3
reverselist(&head2);
// 4) Merge alternate nodes
// Assign dummy Node
*head = newNode(0);
// curr is the pointer to this
// dummy Node, which will be
// used to form the new list
Node* curr = *head;
while (head1 || head2)
{
// First add the element
// from 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;
}
}
// Assign the head of the new
// list to head pointer
*head = (*head)->next;
}
// Driver program
int main()
{
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);
printlist(head); // Print original list
rearrange(&head); // Modify the list
printlist(head); // Print modified list
return 0;
}
Output:
1 -> 2 -> 3 -> 4 -> 5
1 -> 5 -> 2 -> 4 -> 3
Time Complexity: O(n)
Auxiliary Space: O(1)
Thanks to Gaurav Ahirwar for suggesting the above approach.
Another approach:
1. Take two pointers prev and curr, which hold the addresses of head and head-> next.
2. Compare their data and swap.
After that, a new linked list is formed.
Below is the implementation:
C++
// C++ code to rearrange linked list
// in place
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node* next;
};
typedef struct node Node;
// Function for rearranging a
// linked list with high and low
// value.
void rearrange(Node* head)
{
// Base case.
if (head == NULL)
return;
// Two pointer variable.
Node *prev = head,
*curr = head->next;
while (curr)
{
// Swap function for swapping data.
if (prev->data > curr->data)
swap(prev->data, curr->data);
// Swap function for swapping data.
if (curr->next &&
curr->next->data > curr->data)
swap(curr->next->data, curr->data);
prev = curr->next;
if (!curr->next)
break;
curr = curr->next->next;
}
}
// Function to insert a node in the
// linked list at the beginning.
void push(Node** head, int k)
{
Node* tem = (Node*)malloc(sizeof(Node));
tem->data = k;
tem->next = *head;
*head = tem;
}
// Function to display node of
// linked list.
void display(Node* head)
{
Node* curr = head;
while (curr != NULL)
{
printf("%d ", curr->data);
curr = curr->next;
}
}
// Driver code
int main()
{
Node* head = NULL;
// Let create a linked list.
// 9 -> 6 -> 8 -> 3 -> 7
push(&head, 7);
push(&head, 3);
push(&head, 8);
push(&head, 6);
push(&head, 9);
rearrange(head);
display(head);
return 0;
}
Output:
6 9 3 8 7
Time Complexity : O(n)
Auxiliary Space : O(1)
Thanks to Aditya for suggesting this approach.
Another Approach: (Using recursion)
- Hold a pointer to the head node and go till the last node using recursion
- Once the last node is reached, start swapping the last node to the next of head node
- Move the head pointer to the next node
- Repeat this until the head and the last node meet or come adjacent to each other
- Once the Stop condition met, we need to discard the left nodes to fix the loop created in the list while swapping nodes.
C++
// C/C++ program to implement
// the above approach
#include <stdio.h>
#include <stdlib.h>
// Creating the structure
// for node
struct Node
{
int data;
struct Node* next;
};
// Function to create newNode
// in a linkedlist
struct Node* newNode(int key)
{
struct Node* temp =
malloc(sizeof(struct Node));
temp->data = key;
temp->next = NULL;
return temp;
}
// Function to print the list
void printlist(struct Node* head)
{
while (head)
{
printf("%d ", head->data);
if (head->next)
printf("->");
head = head->next;
}
printf("");
}
// Function to rearrange
void rearrange(struct Node** head,
struct Node* last)
{
if (!last)
return;
// Recursive call
rearrange(head, last->next);
// (*head)->next will be set to NULL
// after rearrangement.
// Need not do any operation further
// Just return here to come out of recursion
if (!(*head)->next)
return;
// Rearrange the list until both head
// and last meet or next to each other.
if ((*head) != last && (*head)->next != last)
{
struct Node* tmp = (*head)->next;
(*head)->next = last;
last->next = tmp;
*head = tmp;
}
else
{
if ((*head) != last)
*head = (*head)->next;
(*head)->next = NULL;
}
}
// Drivers Code
int main()
{
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);
// Print original list
printlist(head);
struct Node* tmp = head;
// Modify the list
rearrange(&tmp, head);
// Print modified list
printlist(head);
return 0;
}
Output:
1 ->2 ->3 ->4 ->5
1 ->5 ->2 ->4 ->3
Time Complexity: O(n), where n represents the length of the given linked list.
Auxiliary Space: O(n), for recursive stack where n represents the length of the given linked list.
Please refer complete article on Rearrange a given linked list in-place. for more details!
Similar Reads
C++ Program For Insertion Sort In A Singly Linked List We have discussed Insertion Sort for arrays. In this article we are going to discuss Insertion Sort for linked list. Below is a simple insertion sort algorithm for a linked list. 1) Create an empty sorted (or result) list. 2) Traverse the given list, do following for every node. ......a) Insert curr
5 min read
C++ Program For Reversing A Doubly Linked List Given a Doubly Linked List, the task is to reverse the given Doubly Linked List. See below diagrams for example. (a) Original Doubly Linked List (b) Reversed Doubly Linked List Here is a simple method for reversing a Doubly Linked List. All we need to do is swap prev and next pointers for all nodes
5 min read
C++ Program For Inserting A Node In A Linked List Inserting a node into a linked list can be done in several ways, depending on where we want to insert the new node. Here, we'll cover four common scenarios: inserting at the front of the list, after a given node, at a specific position, and at the end of the listTable of ContentInsert a Node at the
9 min read
C++ Program For Making Middle Node Head In A Linked List Given a singly linked list, find middle of the linked list and set middle node of the linked list at beginning of the linked list. Examples: Input: 1 2 3 4 5 Output: 3 1 2 4 5 Input: 1 2 3 4 5 6 Output: 4 1 2 3 5 6 The idea is to first find middle of a linked list using two pointers, first one moves
3 min read
C++ Program For Writing A Function To Delete A Linked List Algorithm For C++:Iterate through the linked list and delete all the nodes one by one. The main point here is not to access the next of the current pointer if the current pointer is deleted. Implementation: C++ // C++ program to delete a linked list #include <bits/stdc++.h> using namespace std
2 min read
C++ Program For Pairwise Swapping Elements Of A Given Linked List By Changing Links Given a singly linked list, write a function to swap elements pairwise. For example, if the linked list is 1->2->3->4->5->6->7 then the function should change it to 2->1->4->3->6->5->7, and if the linked list is 1->2->3->4->5->6 then the function sh
5 min read
C++ Program For Swapping Nodes In A Linked List Without Swapping Data Given a linked list and two keys in it, swap nodes for two given keys. Nodes should be swapped by changing links. Swapping data of nodes may be expensive in many situations when data contains many fields. It may be assumed that all keys in the linked list are distinct. Examples: Input : 10->15-
5 min read
C++ Program for Deleting a Node in a Linked List Write a C++ program to delete a node from the given link list.ExamplesInput: Linked List: 10 -> 20 -> 30 -> 40 -> 50, Position to delete: 3Output: 10 -> 20 -> 40 -> 50Explanation: The node at position 3 is removed. The list then connects node 20 directly to node 40.Input: Linked
6 min read
C++ Program For Inserting Node In The Middle Of The Linked List Given a linked list containing n nodes. The problem is to insert a new node with data x at the middle of the list. If n is even, then insert the new node after the (n/2)th node, else insert the new node after the (n+1)/2th node. Examples: Input : list: 1->2->4->5 x = 3 Output : 1->2->
5 min read
C++ Program for Clockwise rotation of Linked List Given a singly linked list and an integer K, the task is to rotate the linked list clockwise to the right by K places.Examples: Input: 1 -> 2 -> 3 -> 4 -> 5 -> NULL, K = 2 Output: 4 -> 5 -> 1 -> 2 -> 3 -> NULLInput: 7 -> 9 -> 11 -> 13 -> 3 -> 5 -> NULL
4 min read