Reverse a linked list
Given pointer to the head node of a linked list, the task is to reverse the linked list. We need to reverse the list by changing the links between nodes.
Examples:
Input: Head of following linked list
1->2->3->4->NULL
Output: Linked list should be changed to,
4->3->2->1->NULLInput: Head of following linked list
1->2->3->4->5->NULL
Output: Linked list should be changed to,
5->4->3->2->1->NULLInput: NULL
Output: NULL
Input: 1->NULL
Output: 1->NULL
Recursively Reversing a linked list [A simple implementation]
Given pointer to the head node of a linked list, the task is to recursively reverse the linked list. We need to reverse the list by changing links between nodes.
Examples:
Input : Head of following linked list 1->2->3->4->NULL Output : Linked list should be changed to, 4->3->2->1->NULL Input : Head of following linked list 1->2->3->4->5->NULL Output : Linked list should be changed to, 5->4->3->2->1->NULL Input : NULL Output : NULL Input : 1->NULL Output : 1->NULLReverse a Linked List C++ Code [Iterative and Recursive]
Many of you must be familiar with the application of a linked list in the real world and its importance. We use linked lists to maintain a directory of names, dynamic allocation of memory, and create an implementation of essentials data structures like stacks and queues, and what not?
Knowing all this in this tutorial we are going to discuss the basic understanding of a linked list, and implement and analyze how to reverse a linked list in C++. Let’s get Kraken!
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include #include // A Linked List Node struct Node { int data; struct Node* next; }; // Helper function to print a given linked list void printList[struct Node* head] { struct Node* ptr = head; while [ptr] { printf["%d —> ", ptr->data]; ptr = ptr->next; } printf["NULL\n"]; } // Helper function to insert a new node at the beginning of the linked list void push[struct Node** head, int data] { struct Node* newNode = [struct Node*]malloc[sizeof[struct Node]]; newNode->data = data; newNode->next = *head; *head = newNode; } // Recursive function to reverse a given linked list. It reverses the // given linked list by fixing the head pointer and then `.next` // pointers of every node in reverse order void recursiveReverse[struct Node* head, struct Node** headRef] { struct Node* first; struct Node* rest; // empty list base case if [head == NULL] { return; } first = head; // suppose first = {1, 2, 3} rest = first->next; // rest = {2, 3} // base case: the list has only one node if [rest == NULL] { // fix the head pointer here *headRef = first; return; } // recursively reverse the smaller {2, 3} case // after: rest = {3, 2} recursiveReverse[rest, headRef]; // put the first item at the end of the list rest->next = first; first->next = NULL; // [tricky step — make a drawing] } // Reverse a given linked list. The function takes a pointer // [reference] to the head pointer void reverse[struct Node** head] { recursiveReverse[*head, head]; } int main[void] { // input keys int keys[] = { 1, 2, 3, 4, 5, 6 }; int n = sizeof[keys]/sizeof[keys[0]]; struct Node* head = NULL; for [int i = n - 1; i >=0; i--] { push[&head, keys[i]]; } reverse[&head]; printList[head]; return 0; } |
DownloadRun Code
Output:
6 —> 5 —> 4 —> 3 —> 2 —> 1 —> NULL
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #include #include // A Linked List Node struct Node { int data; struct Node* next; }; // Helper function to print a given linked list void printList[struct Node* head] { struct Node* ptr = head; while [ptr] { printf["%d —> ", ptr->data]; ptr = ptr->next; } printf["NULL\n"]; } // Helper function to insert a new node at the beginning of the linked list void push[struct Node** head, int data] { struct Node* newNode = [struct Node*]malloc[sizeof[struct Node]]; newNode->data = data; newNode->next = *head; *head = newNode; } // Reverses a given linked list by changing its `.next` pointers and // its head pointer. Takes a pointer [reference] to the head pointer void reverse[struct Node** head] { struct Node* previous = NULL; // the previous pointer struct Node* current = *head; // the main pointer // traverse the list while [current != NULL] { // tricky: note the next node struct Node* next = current->next; current->next = previous;// fix the current node // advance the two pointers previous = current; current = next; } // fix the head pointer to point to the new front *head = previous; } int main[void] { // input keys int keys[] = { 1, 2, 3, 4, 5, 6 }; int n = sizeof[keys]/sizeof[keys[0]]; struct Node* head = NULL; for [int i = n - 1; i >=0; i--] { push[&head, keys[i]]; } reverse[&head]; printList[head]; return 0; } |
DownloadRun Code
Output:
6 —> 5 —> 4 —> 3 —> 2 —> 1 —> NULL
Java Program to Reverse a singly linked list using recursion and Iteration
A linked list is a data structure which contains nodes, every node keep data and pointer to the next node. This way linked list grows and can store as many elements as much memory allows it. It's not like an array that requires a contiguous chunk of memory because here node can be stored at any memory location.This structure means, adding and removing elements in a linked list is easy but searching an element is expensive because you need to traverse the entire list to find the element. It doesn't help even if you know that element is the 5th node or 6th node because you cannot access them by index like an array.
This is the biggest difference between an array and a linked list data structure. In the array, searching the index is O[1] operation but in linked list searching is O[n] operation.
It divides the list into two parts first node and rest of the list,and then link rest to head in reverse order. It then recursively applies the same division until it reaches the last node, at that point whole linked list, is reversed.
Coming back to our code which represents a singly linked list in Java [see the next section], with limited operations. I have already removed some non-relevant code for performing different operations on a linked list likechecking if the linked list is cyclic or not, inserting an element at the middle, and removing the element. Since we don't need this code for reversing a linked list, I have simply deleted them for now.
This class is similar to theSinglyLinkedListclass, which we have seen in how to implement a linked list in Java using generics [seehere], with two more methods for reversing linked list using iteration and recursion.
The reverseRecursively[]methodreverses the linked list using recursion. It uses the call stack to store data, and once we reached tail, which becomes the new head for the reversed linked list, it starts adding nodes in reverse order. Look at some comments around those methods, which will make you understand the algorithm of reversing the linked list better.
Btw, If you are not very familiar with a linked list data structure or want to learn more about linked list data structure, you should first read a good course on data structure and algorithm likeAlgorithms and Data Structures - Part 1 and 2on Pluralsight, one of the best course to learn data structure and algorithms.