Write a function to reverse a linked list
August 2, 2009
Iterative Method
Iterate trough the linked list. In loop, change next to prev, prev to current and current to next.
Implementation of Iterative Method
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct node
{
int data;
struct node* next;
};
/* Function to reverse the linked list */
static void reverse(struct node** head_ref)
{
struct node* prev = NULL;
struct node* current = *head_ref;
struct node* next;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
/* Function to push a node */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node =
(struct node*) malloc(sizeof(struct 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(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
}
/* Drier program to test above function*/
int main()
{
/* Start with the empty list */
struct node* head = NULL;
push(&head, 20);
push(&head, 4);
push(&head, 15);
push(&head, 85);
printList(head);
reverse(&head);
printf("\n Reversed Linked list \n");
printList(head);
getchar();
}
Time Complexity: O(n)
Space Complexity: O(1)
Recursive Method:
1) Divide the list in two parts - first node and rest of the linked list. 2) Call reverse for the rest of the linked list. 3) Link rest to first. 4) Fix head pointer

void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest;
/* empty list */
if (*head_ref == NULL)
return;
/* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next;
/* List has only one node */
if (rest == NULL)
return;
/* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first;
/* tricky step -- see the diagram */
first->next = NULL;
/* fix the head pointer */
*head_ref = rest;
}
Time Complexity: O(n)
Space Complexity: O(1)
References:
http://cslibrary.stanford.edu/105/LinkedListProblems.pdf
- Write a function to delete a Linked List
- Write a function that counts the number of times a given int occurs in a Linked List
- Write a function to get Nth node in a Linked List
- Write a C function to print the middle of a given linked list
- Given only a pointer to a node to be deleted in a singly linked list, how do you delete it?
This it the best solution and easiest one also .
void revByRecursion(Link **start) {
static Link *tmp = NULL ;
static Link *tmpStart = NULL ;
static int x = 0 ;
if(*start == NULL)
return ;
x++ ;
revByRec(&((*start)->nxt));
x--;
if(tmp == NULL){
tmp = *start;
tmpStart = *start ;
}
else {
tmp->nxt = *start;
tmp = tmp->nxt ;
}
if(x==0){
tmp->nxt = NULL ;
*start = tmpStart ;
}
}void revByRec(Link **start) {
static Link *tmp = NULL ;
static Link *tmpStart = NULL ;
static int x = 0 ;
if(*start == NULL)
return ;
x++ ;
revByRec(&((*start)->nxt));
x--;
if(tmp == NULL){
tmp = *start;
tmpStart = *start ;
}
else {
tmp->nxt = *start;
tmp = tmp->nxt ;
}
if(x==0){
tmp->nxt = NULL ;
*start = tmpStart ;
}
}
Sorry above was wrong paste :
Below is correct one
void revByRec(Link **start) {
static Link *tmp = NULL ;
static Link *tmpStart = NULL ;
static int x = 0 ;
if(*start == NULL)
return ;
x++ ;
revByRec(&((*start)->nxt));
x--;
if(tmp == NULL){
tmp = *start;
tmpStart = *start ;
}
else {
tmp->nxt = *start;
tmp = tmp->nxt ;
}
if(x==0){
tmp->nxt = NULL ;
*start = tmpStart ;
}
}
//this code work for all possibilities and use only one (extra)pointer like in question
list* deletenode(list *head,int d)
{
list *t=head;
if(head==NULL) return head;
if(head->next==NULL)
{
if(head->val==d)
{
head=NULL;
return head;
}
}
else
if(head->val==d)
{
head=head->next;
return head;
}
while(t->next!=NULL && t->next->val!=d)
t=t->next;
if(t->next==NULL) return head;
if(t->next->val==d)
t->next=t->next->next;
return head;
}
plz tell in recursive method hw the head wil able to point to first node....coz rest has diff everytym and in last rest will point to 2nd node(new second last node) ...but still head point to new first...hw?
plz tell in recursive method hw the head wil able to point to first node....coz rest has diff everytym and in last rest will point to 2nd node(new second last node) ...but still head point to new first...hw?
A simpler Solution
While ( Start != End of Linked list) {
Delete from First
Insert at First
}
Recursive and Iterative procedures:
struct node* recursiveReverse(struct node* list) { struct node* retHead; if( list == NULL || list->next == NULL ) { return list; } retHead = recursiveReverse(list->next); list->next->next = list; list->next = NULL; return retHead; } struct node* reverse(struct node* head) { struct node* rHead = NULL; struct node* current = head; while( current ) { head = head->next; current->next = rHead; rHead = current; current = head; } return rHead; }sir correct me if i am wrong but i think in the above recursive procedure we will have the address of last node of reversed linked list as a final return value.
For example
1 2 3 4 5
5 4 3 2 1
we will have the address of node 1 which is at the last
Since the links are now reversed and we only have the address of last node it would become impossible to traverse the list in future
i think we should modify that recursive procedure to incorporate the necessary change
struct node *reverse(struct node **head,struct node *t){ if(t->link) reverse(head,t->link)->link=t; else *head=t; // when base condition is reached t->link=NULL; return t; }Please stop mentioning "Sir".
I don't see any issue with my code. Recursion is powerful and complex technique. We should not prefer it unless the algorithm demands it.
I would recommend to draw a linked list on paper (try all corner cases of 0, 1, 2 and 3 length), and analyze recursive code step by step. Rearrange the links as you go through the code. It will make the logic clear.
Dual reference (pointer to pointer) makes code little error prone, if not now, in future. It would be good to add encapsulation over core data structure to avoid multiple level pointers.
Recursive procedure can be as follows;
/* Function to reverse the linked list */ struct node* reverse(struct node* head_ref) { struct node* current = head_ref; // Defined only once. static struct node* prev = NULL; static struct node* next; if (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; // no need of saving the return value in any pointer. reverse(current); } else return; // By the virtue of being static variable, pre will // retain the last value, not the one, which is local // to the function. return pre; } main() { struct node *head; // Code for making the list, pointed by head struc pointer. head = reverse(head); } /* There is one issue with the code. Here the value of pre will be returned times equal to number of nodes minus one, however used only last time. Mind you, all the time, the same values has been returned, the address of the last node (which will then be assigned to the list pointer), since pre is an static pointer. */This also works:
Node p1 = head; Node p2 = p1->next; Node temp = null; while(p1!=null) { p1->next = temp; temp = p1; p1 = p2; if(p2!=null) { p2=p2->next; } } head = temp;reverse a linklist using one extra pointer
struct node * reverse_ll( struct node * head) { struct node * temp = NULL; if ( head == NULL) return NULL; if ( head->next == NULL ) return head; temp = reverse_ll ( head->next ); head->next -> next = head; head->next = NULL; return temp; }