Reputation: 1529
I have simple link list program, that would create/print it, and later on print the last 2 number from it (in reverse order)
cat link_list.c
/**
* C program to create and traverse a Linked List
*/
#include <stdio.h>
#include <stdlib.h>
/* Structure of a node */
struct node {
int data; // Data
struct node *next; // Address
}*head;
/*
* Functions to create and display list
*/
void createList(int n);
void traverseList();
void ReverseList(struct node *);
int main()
{
int n;
printf("Enter the total number of nodes: ");
scanf("%d", &n);
createList(n);
printf("\nData in the list \n");
traverseList();
ReverseList(head);
return 0;
}
/*
* Create a list of n nodes
*/
void createList(int n)
{
struct node *newNode, *temp;
int data, i;
head = (struct node *)malloc(sizeof(struct node));
// Terminate if memory not allocated
if(head == NULL)
{
printf("Unable to allocate memory.");
exit(0);
}
// Input data of node from the user
printf("Enter the data of node 1: ");
scanf("%d", &data);
head->data = data; // Link data field with data
head->next = NULL; // Link address field to NULL
// Create n - 1 nodes and add to list
temp = head;
for(i=2; i<=n; i++)
{
newNode = (struct node *)malloc(sizeof(struct node));
/* If memory is not allocated for newNode */
if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
printf("Enter the data of node %d: ", i);
scanf("%d", &data);
newNode->data = data; // Link data field of newNode
newNode->next = NULL; // Make sure new node points to NULL
temp->next = newNode; // Link previous node with newNode
temp = temp->next; // Make current node as previous node
}
}
/*
* Display entire list
*/
void traverseList()
{
struct node *temp;
// Return if list is empty
if(head == NULL)
{
printf("List is empty.");
return;
}
temp = head;
while(temp != NULL)
{
printf("Data = %d\n", temp->data); // Print data of current node
temp = temp->next; // Move to next node
}
}
static count=0, k=2;
ReverseList(struct node *head)
{
if (head == NULL)
return;
else {
ReverseList(head->next);
count++;
if (count <= k)
printf("Data = %d\n", head->data);
}
}
For an input 1 2 3 , it would first print 3 2 1 and then 3 2 correctly but I have confusion about the :
if (head == NULL)
return;
what exactly it returns with return;, and where head is pointing after the
ReverseList(head->next); statement ?
Upvotes: 1
Views: 104
Reputation: 311068
For starters you forgot to specify the return type of the function in the function definition:
ReverseList(struct node *head)
{
if (head == NULL)
return;
else {
ReverseList(head->next);
count++;
if (count <= k)
printf("Data = %d\n", head->data);
}
}
You have to write:
void ReverseList(struct node *head)
As for your question:
I have confusion about the :
if (head == NULL) return;
what exactly it returns with return;, and where head is pointing after the ReverseList(head->next); statement ?
Then as the function has the return type void
and the return statement does not include an expression then the return statement returns nothing.
The function parameter head
is a local variable of the function. The function does not change the pointer head declared in the file scope
struct node {
int data; // Data
struct node *next; // Address
}*head;
In the first call of the function the parameter head has the value of the global variable head due to this statement:
ReverseList(head);
If the value is not equal to NULL then the function recursively calls itself passing the value of the pointer head->next
:
ReverseList(head->next);
So in the second recursive call of the function itself the value of its parameter head
is equal to the value of head->next
where in this expression head
is the function parameter of the previous call of the function.
That is the parameter head at first gets the value of the global variable head
and then the parameter is initialized sequentially by values of the data member next
of the next node in the sequence.
So for the list that contains nodes with values 1, 2, 3 you have
1-st call parameter head is equal to the global variable head
2-nd call parameter head is equal to head->next that points to the node with the value 1
3-rd call parameter head is equal to head->next->next that points to the node with the value 2
4-th call parameter head is equal to head->next->next->next that points to the node with the value 3
5-th call parameter head is equal to head->next->next->next->next and equal to NULL
Pay attention to that it is not a good idea to use static global variables within the function
static count=0, k=2;
You need to remember reinitialize them if you want to call the function one more time. It is better to make the variable k
a function parameter.
The function could be defined the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
int push( struct node **head, int data )
{
struct node *new_node = malloc( sizeof( *new_node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
void display( const struct node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
size_t display_last_n( const struct node *head, size_t n )
{
size_t i = 0;
if ( head != NULL )
{
i = display_last_n( head->next, n ) + 1;
if ( !( n < i ) )
{
if ( i != 1 ) printf( ", " );
printf( "%d", head->data );
}
}
return i;
}
void clear( struct node **head )
{
while ( *head )
{
struct node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
}
int main(void)
{
struct node *head = NULL;
const int N = 10;
for ( int n = N; n--; )
{
push( &head, n );
}
display( head );
for ( size_t i = 0; i < N; i++ )
{
display_last_n( head, i + 1 );
putchar( '\n' );
}
clear( &head );
return 0;
}
The program output is:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
9
9, 8
9, 8, 7
9, 8, 7, 6
9, 8, 7, 6, 5
9, 8, 7, 6, 5, 4
9, 8, 7, 6, 5, 4, 3
9, 8, 7, 6, 5, 4, 3, 2
9, 8, 7, 6, 5, 4, 3, 2, 1
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
Upvotes: 0
Reputation: 409374
Lets say we have a simple three-node list like this:
1 -> 2 -> 3
When we initially call ReverseList
we pass the 1
node as the head
and we have this call-chain:
ReverseList(1 -> 2 -> 3 -> NULL) ReverseList(2 -> 3 -> NULL) ReverseList(3 -> NULL) ReverseList(NULL) printf(3) printf(2) printf(1)
Upvotes: 1