Problem Statement
The objective is to reverse a given linked list, which involves altering the pointers between nodes such that the last node becomes the new head node, and each subsequent node points to its predecessor.
For Example:
Input1 :
2->3->4->5->NULL
Output1 :
5->4->3->2->NULL
Input2 :
5->NULL
Output2 :
5->NULL
Input3 :
NULL
Output3 :
NULL
Approach 1 : Iterative Method
First, that is the iterative approach to reverse a linked list is given below.
Algorithm
- Initialize three-pointers that are curr, prev, and next with NULL values.
- Go through the linked list iteratively.
Perform the following in a loop :
// Store the next node before changing the current’s next.
next = curr->next
// Now change the next of the current. That’s where the real reversing takes place.
curr->next = prev
// Advance prev and curr by one step.
prev = curr
curr = next
Code Implementation
- In C++
// Iterative program
#include <iostream>
using namespace std;
/* Linked list node structure*/
struct node {
int val;
struct node* next;
Node(int val){
this->val = val;
next = NULL;
}
};
struct Linked_List {
node* head;
Linked_List() { head = NULL; }
/* Function for reversing linked list */
void reverse_ll(){
// Set the pointers for the current, previous, and next values.
node* curr = head;
node *prev = NULL, *next = NULL;
while (curr != NULL) {
// Storing next
next = curr->next;
// Reversing current node pointer
curr->next = prev;
// Move all 3 pointers to one position ahead.
prev = curr;
curr = next;
}
head = prev;
}
/* Function for printing linked list */
void print_ll(){
struct node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
void push(int data){
node* temp = new node(data);
temp->next = head;
head = temp;
}
};
/* Driver code*/
int main(){
Linked_List llist;
llist.push(2);
llist.push(4);
llist.push(6);
llist.push(8);
cout << "Original Linked List\n";
llist.print_ll();
llist.reverse_ll();
cout << "\nFinal Reversed Linked List \n";
ll.print();
return 0;
}
- In Java
// Java program for reversing the linked list
class Linked_List {
static Node head;
static class Node {
int data;
Node next;
Node(int val) {
data = val;
next = null;
}
}
/* Function for reversing the linked list */
Node reverse_linkedlist(Node node) {
Node prev = null;
Node curr = node;
Node next = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
node = prev;
return node;
}
// prints the double linked_list
void print_LinkedList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
// Driver Code
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.head = new Node(85);
list.head.next = new Node(15);
list.head.next.next = new Node(4);
list.head.next.next.next = new Node(20);
System.out.println("Given Linked List");
list.print_LinkedList(head);
head = list.reverse_linkedlist(head);
System.out.println("");
System.out.println("Reversed Linked List ");
list.print_LinkedList(head);
}
}
- In Python
class Node:
# Constructor to initialize the node object
def __init__(self, val):
self.data = val
self.next = None
class Linked_List:
# Function for initializing the head
def __init__(self):
self.head = None
# Function to reverse the linked list
def reverse_ll(self):
prev = None
curr = self.head
while(curr is not None):
next = curr.next
curr.next = prev
prev = curr
curr = next
self.head = prev
# Function for inserting a new node at the beginning of ll
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# function for printing the Linked_List
def printLinkedList(self):
temp = self.head
while(temp):
print temp.data,
temp = temp.next
# Driver code
l_list = Linked_List()
l_list.push(2)
l_list.push(4)
l_list.push(6)
l_list.push(8)
print("Original Linked List")
l_list.printLinkedList()
l_list.reverse_ll()
print("\nFinal Reversed Linked List")
l_list.printLinkedList()
Output :
Original Linked List
2 4 6 8
Final Reversed Linked List
8 6 4 2
Complexity Analysis
Time Complexity :
As we will iterate over the whole linked list of size “n” so the time complexity of this approach will be O(n).
Space Complexity :
As no extra memory is being used in this approach so auxiliary space consumed will be O(1).
Approach 2 : Recursive Method
Second, that is a recursive approach to reverse a linked list is given below.
Algorithm
- The first node and the remainder of the linked list should be separated into two parts.
- For the remaining linked list items, call reverse.
- Link the rest to the first.
- Fix the head pointer.
Code Implementation
- In C++
#include <iostream>
using namespace std;
/* Link list node */
struct Node {
int data;
struct Node* next;
Node(int val){
this->data = val;
next = NULL;
}
};
struct Linked_List {
Node* head;
Linked_List(){
head = NULL;
}
Node* reverse_ll(Node* head){
//checking if linkedlist is empty or there is a single node then return the head of the linkedlist
if (head == NULL || head->next == NULL)
return head;
/* Put the very first element there at the end and flip the rest of the list around. */
Node* rest = reverse_ll(head->next);
head->next->next = head;
head->next = NULL;
return rest;
}
//function to print linked list
void print_linkedlist(){
struct Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
//function for pushing data inside the node
void push_data(int val){
Node* temp = new Node(val);
temp->next = head;
head = temp;
}
};
int main(){
Linked_List llist;
llist.push_data(2);
llist.push_data(4);
llist.push_data(6);
llist.push_data(8);
cout << "Original LinkedList\n";
llist.print_linkedlist(); //call the print function
llist.head = llist.reverse_ll(llist.head); //call the reverse list function
cout << "\nFinal Reversed LinkedList \n";
ll.print_linkedlist(); //call the print function
return 0;
}
- In Java
class recursion {
static Node head; // head of the list
static class Node {
int data;
Node next;
Node(int val) {
data = val;
next = null;
}
}
static Node reversell(Node head) {
if (head == null || head.next == null) return head;
/* Put the very first element there at the end and flip the rest of the list around.*/
Node rest = reversell(head.next);
head.next.next = head;
head.next = null;
/* fixing head pointer */
return rest;
}
/* Function for printing the linked_list */
static void printll() {
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
static void push(int val) {
Node temp = new Node(val);
temp.next = head;
head = temp;
}
/* Driver program*/
public static void main(String args[]) {
push(2);
push(4);
push(6);
push(8);
System.out.println("Original Linked List");
print();
head = reversell(head);
System.out.println("Final Reversed Linked List");
print();
}
}
- In Python
class Node:
def __init__(self, val):
self.data = val
self.next = None
class Linked_List:
def __init__(self):
self.head = None # Head of the list
# Function for reversing the linked list
def reversell(self, head):
# If the head is empty or the list end has been reached
if the head is None or head.next is None:
return head
# Reversing the rest of the list
rest = self.reversell(head.next)
# Put the first element at the end
head.next.next = head
head.next = None
# Fixing header pointer
return rest
# Return linked list in display format
def __str__(self):
linkedList_Str = ""
temp = self.head
while temp:
linkedList_Str = (linkedList_Str +
str(temp.data) + " ")
temp = temp.next
return linkedList_Str
# Pushing the new data at the head of the list
def push_data(self, val):
temp = Node(val)
temp.next = self.head
self.head = temp
# Driver code
linked_List = Linked_List()
linked_List.push_data(2)
linked_List.push_data(4)
linked_List.push_data(6)
linked_List.push_data(8)
print("Original Linked List")
print(linked_List)
linked_List.head = linked_List.reversell(linked_List.head)
print("Final Reversed Linked List")
print(linked_List)
Output :
Original Linked List
2 4 6 8
Final Reversed Linked list
8 6 4 2
Complexity Analysis
Time Complexity :
As we are iterating over the linked list with “n” nodes to reverse it then time complexity will be O(n).
Space Complexity :
As we are using extra “n” size space for performing this approach thus it will consume O(n) auxiliary space.
Approach 3 : Tail Recursive Method
As in the previous two approaches we have used the iterative and recursive methods now here we will use this tail recursive method to reverse a linked list.
Code Implementation
- In C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
void reverse_Util(Node* curr, Node* prev, Node** head);
// this function calls reverseUtil() with prev set to NULL.
void reverse_ll(Node** head){
if (!head)
return;
reverse_Util(*head, NULL, head);
}
// A straightforward function to reverse a linked list that is tail-recursive. Prev is initially passed as NULL.
void reverse_Util(Node* curr, Node* prev, Node** head){
if (!curr->next) {
*head = curr;
/* Updating next to the prev node */
curr->next = prev;
return;
}
/* Saving curr->next node for the recursive call */
Node* next = curr->next;
/* now update the next ..*/
curr->next = prev;
reverse_Util(next, curr, head);
}
// Utility function for creating a new node
Node* newNode(int val){
Node* temp = new Node;
temp->data = val;
temp->next = NULL;
return temp;
}
// Utility function for printing a linked list
void printlinkedlist(Node* head){
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
// Driver code
int main(){
Node* head1 = newNode(2);
head1->next = newNode(4);
head1->next->next = newNode(6);
head1->next->next->next = newNode(8);
cout << "Original Linked List\n";
printlist(head1);
reverse(&head1);
cout << "\nFinal Reversed Linked List\n";
printlinkedlist(head1);
return 0;
}
- In Java
class Linked_List {
static Node head;
static class Node {
int data;
Node next;
Node(int val) {
data = val;
next = null;
}
}
// A simple and tail recursive function to reverse
// a linked list. prev is passed as NULL initially.
Node reverseUtil(Node curr, Node prev) {
/*If the head is initially null OR the list is empty*/
if (head == null) return head;
/* If the last node marks its head*/
if (curr.next == null) {
head = curr;
/* Update next to prev node */
curr.next = prev;
return head;
}
/* Save curr->next node for recursive call */
Node next1 = curr.next;
/* and update next ..*/
curr.next = prev;
reverseUtil(next1, curr);
return head;
}
// prints content of the double-linked list
void printLinkedList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
// Driver Code
public static void main(String[] args) {
Linked_List list = new Linked_List();
list.head = new Node(2);
list.head.next = new Node(4);
list.head.next.next = new Node(6);
list.head.next.next.next = new Node(8);
System.out.println("Original Linked List ");
list.printLinkedList(head);
Node res = list.reverseUtil(head, null);
System.out.println("");
System.out.println("");
System.out.println("Final Reversed Linked List ");
list.printList(res);
}
}
- In Python
class Node:
def __init__(self, val):
self.data = val
self.next = None
class Linked_List:
# Function to initialize head
def __init__(self):
self.head = None
def reverse_Util(self, curr, prev):
# If the last node then mark it as head
if curr.next is None:
self.head = curr
# Update the next to prev node
curr.next = prev
return
# Save the curr.next node for the recursive call
next = curr.next
# And update the next
curr.next = prev
self.reverse_Util(next, curr)
# this function calls reverse_Util() with prev set to NULL.
def reversell(self):
if self.head is None:
return
self.reverse_Util(self.head, None)
def push_data(self,data):
node = Node(data)
node.next = self.head
self.head = node
# function to print linked list
def printllist(self):
temp = self.head
while(temp):
print temp.data,
temp = temp.next
# Driver code
llist = Linked_List()
llist.push_data(8)
llist.push_data(7)
llist.push_data(6)
llist.push_data(5)
llist.push_data(4)
llist.push_data(3)
llist.push_data(2)
llist.push_data(1)
print("Original Linked List")
llist.printllist()
llist.reversell()
print("\nReversed Linked List")
llist.printllist()
Output :
Original Linked List
2 4 6 8
Reversed Linked List
8 6 4 2
Complexity Analysis
Time Complexity :
As we are iterating over the linked list of size “n” for reversing it, so time complexity will be O(n).
Space Complexity :
As no extra space is required in this approach so it will take O(1) auxiliary space.
Approach 4: Using Stack
Algorithm
- Store the values in the stack until all the values are entered.
- Update a Head pointer to a final location(last node) once all entries have been made.
- Until the stack is empty, begin popping up the nodes and storing them in the same order.
- Update the last Node’s next pointer in the stack with NULL.
Code Implementation
- In C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
};
// Method for reversing a linked list
void reverse_ll(Node** head){
// Create stack "st"
stack<Node*> st;
Node* temp = *head;
while (temp->next != NULL) {
st.push(temp);
temp = temp->next;
}
*head = temp;
while (!st.empty()) {
// Storing the top value of the stack
temp->next = st.top();
// Poping up value from the stack
st.pop();
// updating the next pointer in the list
temp = temp->next;
}
temp->next = NULL;
}
// Method for Displaying elements in the List
void printllist(Node* temp){
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
// inserting back the linked list
void insert_backll(Node** head, int val){
Node* temp = new Node();
temp->data = val;
temp->next = NULL;
if (*head == NULL) {
*head = temp;
return;
}
else {
Node* lastnode = *head;
while (lastnode->next != NULL)
lastnode = lastnode->next;
lastnode->next = temp;
return;
}
}
int main(){
Node* head = NULL;
insert_backll(&head, 2);
insert_backll(&head, 4);
insert_backll(&head, 6);
insert_backll(&head, 8);
cout << "Original Linked List\n";
printllist(head);
reverse_ll(&head);
cout << "\nFinal Reversed Linked List\n";
printllist(head);
return 0;
}
- In Java
import java.util.*;
class LinkedList {
static class Node {
int data;
Node next;
};
static Node head = null;
// Method for reversing a linked list
static void reverse_ll(){
// Creating stack "s"
Stack<Node> st = new Stack<>();
Node temp = head;
while (temp.next != null)
st.add(temp);
temp = temp.next;
}
head = temp;
while (!st.isEmpty()) {
// Storing the top value of the stack in the list
temp.next = st.peek();
// Poping up the value from the stack
st.pop();
// updating the next pointer in the list
temp = temp.next;
}
temp.next = null;
}
// Method for Displaying elements in the List
static void printllist(Node temp){
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
}
static void insert_backll(int value){
Node temp = new Node();
temp.data = value;
temp.next = null;
if (head == null) {
head = temp;
return;
}
else {
Node lastnode = head;
while (lastnode.next != null)
lastnode = lastnode.next;
lastnode.next = temp;
return;
}
}
public static void main(String[] args){
insert_backll(1);
insert_backll(2);
insert_backll(3);
insert_backll(4);
System.out.print("Original Linked List\n");
printllist(head);
reverse_ll();
System.out.print("\nFinal Reversed Linked List\n");
printllist(head);
}
}
- In Python
class LListNode:
def __init__(self, data=0, next=None):
self.val = data
self.next = next
class Solution:
def reverse_ll(self, head):
st, temp = [], head
while temp:
st.append(temp)
temp = temp.next
head = temp = st.pop()
while len(st) > 0:
temp.next = st.pop()
temp = temp.next
temp.next = None
return head
if __name__ == "__main__":
head = LListNode(2, LListNode(4, LListNode(6,
LListNode(8, LListNode(10)))))
obj = Solution()
head = obj.reverse_ll(head)
while head:
print(head.val, end=' ')
head = head.next
Output :
Original Linked List
2 4 6 8
Final Reversed Linked List
8 6 4 2
Complexity Analysis
Time Complexity :
As we are iterating over the linked list of size “n” for reversing it so time complexity will be O(n).
Space Complexity :
As we are creating a stack and storing “n” nodes values in it. Here “n” is the size of the linked list. So O(n) auxiliary space is used here.
Conclusion
- We have seen five approaches to reverse a linked list.These are :
- Iterative Method,
- Recursive Method,
- Tail Recursive Method,
- Using Array,
- Using Stack.
- An iterative method is the best one for reversing the linked list under O(n) time complexity and O(1) space complexity.
- Using the stack approach takes O(n) time and space for reversing the linked list.