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 ?
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)
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
Related
In the code below, I try to change the first node with another node from the list. The problem is that I can't do it, I've been struggling for two days, and I still can't figure it out.
Description code :
enter the number of nodes from the keyboard.
pos1 = 1 - the position of the first node in the list
pos2 - the position of the node to be changed with the first node.
In the function Node *createLinkedList(int n) I create the list of nodes, the function void displayList(Node *head) displays the list, the function void swapFirstNode(Node *head, int pos1, int pos2) should exchange the first node with the node a whose position is read from the keyboard.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node;
Node *createLinkedList(int n);
void displayList(Node *head);
void swapFirstNode(Node *head, int pos1, int pos2);
int main()
{
int n, pos1, pos2;
Node *HEAD = NULL;
printf("\n Enter the number of nodes : ");
scanf("%d", &n);
HEAD = createLinkedList(n);
displayList(HEAD);
printf("\n Enter first node position to swap : ");
scanf("%d", &pos1);
printf("\n Enter second node position to swap : ");
scanf("%d", &pos2);
if(pos1 == 1 && pos2 != 1)
swapFirstNode(HEAD, pos1, pos2);
displayList(HEAD);
}
Node *createLinkedList(int n)
{
int i, value;
Node *head = NULL;
Node *temp = NULL;
Node *curr = NULL;
head = (struct node*)malloc(sizeof(struct node));
if(head == NULL)
{
printf("\n Memory can not be allocated!");
}
else
{
printf("\n Input data for node 1 : ");
scanf("%d", &value);
head->data = value;
head->next = NULL;
temp = head;
for(i=2; i<=n; i++)
{
curr = (struct node *)malloc(sizeof(struct node));
if(curr == NULL)
{
printf(" Memory can not be allocated.");
break;
}
else
{
printf("\n Input data for node %d : ", i);
scanf("%d", &value);
curr->data = value;
curr->next = NULL;
temp->next = curr;
temp = temp->next;
}
}
}
return head;
}
void displayList(Node *head)
{
Node *curr = head;
printf("\n");
printf(" ");
while(curr != NULL)
{
printf("%d->", curr->data);
curr = curr->next;
}
printf("NULL\n");
}
void swapFirstNode(Node *head, int pos1, int pos2)
{
Node *curr = head, *node1 = NULL, *node2 = NULL, *prev_node1 = NULL, *prev_node2 = NULL, *temp = NULL;
int counter = 0, value, i = 1;
/// Find out how many nodes are in list
while(curr != NULL)
{
counter++;
curr = curr->next;
}
if(pos1 < 1 || pos1 > counter || pos2 < 1 || pos2 > counter)
exit(0);
/// Retain the maxim value between two position entered from the keyboard
value = pos1 > pos2 ? pos1 : pos2;
curr = head;
node1 = curr;
while(curr != NULL && i <= value)
{
if(pos2 != 1)
{
/// Set the previous node (the node before the second node), regarding the pos2-1
if(i == (pos2-1))
prev_node2 = curr;
/// Set the seconde node, regarding the pos2 entered from the keyboard
if(i == pos2)
node2 = curr;
}
curr = curr->next;
i++;
}
/// Try to swap the two nodes
if(node1 != NULL && node2 != NULL)
{
if(prev_node2 != NULL)
{
temp = head;
node1->next = node2->next;
node2 = temp;
prev_node2->next = node1;
node2->next = temp->next;
}
}
}
I'm sorry. I get dizzy trying to keep track of all of those counters and pointers and everything.
KISS
The following works quite well swapping the head node with another further down the list. Earlier validation ensures that pos > 1 (the user's idea of "first" node) and pos <= n, the count of the number of nodes in the LL. (ie. The user enters 'swap node 2' and this function is called with n - 1. The function then works with the head being considered node 0.)
Notice that the address of the pointer head is received as a ptr-to-ptr. This allows the function to update the caller's variable. Essential in this case because the function is definitely changing the LL's first node!
Anyway, walk & think your way through these lines. I hope it helps show that fewer moving parts can be more effective.
void swapFirstNode( Node **head, int pos ) {
Node *prev = *head, *cut;
if( pos == 1 ) { // special case of 1st & 2nd swapping
cut = prev->next;
prev->next = prev->next->next;
cut->next = prev;
} else {
while( --pos )
prev = prev->next; // Now pointing at node AHEAD of node to swap out.
cut = prev->next;
Node *cont = cut->next; // Now pointing at continuation (if any)
cut->next = (*head)->next; // Now two heads
prev->next = *head; // head spliced onto 1st section
(*head)->next = cont; // old head joined to continuation
}
*head = cut; // This is the new head!
}
I asked for clarification regarding pos1 but didn't get any so I just disregard that. swapFirstNode will always swap with the first node so pos1 will not be needed.
In order to do the swap, I suggest iterating from head pos2 times, then perform a swap of head->data and the data at the Node you're currently pointing at.
Example:
// pos2 is in the range [0, number of elements)
void swapFirstNode(Node *head, int pos2) {
Node *curr = head;
while(pos2-- > 0 && curr) curr = curr->next;
if(!curr) return; // pos2 was out of bounds
// swap
int tmp = curr->data;
curr->data = head->data;
head->data = tmp;
}
Note: pos2 is zero-based as-is common practice in C. You may present 1-based indices to the user, but I suggest not using 1-based arrays/lists in the rest of the code.
For starters the function createLinkedList has an unpredictable behavior because it creates a node even when the user passes to the function a non-positive value.
Node *createLinkedList(int n)
{
int i, value;
Node *head = NULL;
Node *temp = NULL;
Node *curr = NULL;
head = (struct node*)malloc(sizeof(struct node));
//...
At first it should check the value of the parameter n before starting creating nodes. Also the parameter should have an unsigned integer type as for example size_t because negative values do not make a sense.
The parameter of the function displayList should be declared with qualifier const because the function does not change the displayed list.
void displayList( const Node *head );
In C indices start from 0 not from 1. The index 0 corresponds to the head node.
Calculating the number of nodes in the list
while(curr != NULL)
{
counter++;
curr = curr->next;
}
is inefficient. For example if you want to swap the first two nodes then there is no sense to count all nodes in the list.
And if the user specified invalid positions then the program shall not end abruptly as in your function
if(pos1 < 1 || pos1 > counter || pos2 < 1 || pos2 > counter)
exit(0);
It is enough to report to the user that nodes were not swapped because the user specified invalid positions.
And the pointer to the head node must be passed by reference that is through a pointer to it because the pointer to the head node can be changed within the function.
So the function should be declared like
int swapFirstNode( Node **head, size_t pos1, size_t pos2 );
That is the function returns integer value 1 in case of success or 0 otherwise.
What you need to swap two nodes is to swap the pointers that point to the nodes and their data members next that in turn are pointers.
So write an auxiliary function swap that will swap two pointers.
Here is a demonstration program that shows how it can be done.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node;
Node * createLinkedList( const int a[], size_t n )
{
Node *head = NULL;
Node **current = &head;
while ( n-- && ( *current = malloc( sizeof( Node ) ) ) != NULL )
{
( *current )->data = *a++;
( *current )->next = NULL;
current = &( *current )->next;
}
return head;
}
void displayList( const Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
void swap( Node **ptr1, Node **ptr2 )
{
Node *tmp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = tmp;
}
int swapFirstNode( Node **head, size_t pos1, size_t pos2 )
{
int success = 0;
if ( pos1 != pos2 )
{
if ( pos2 < pos1 )
{
size_t tmp = pos1;
pos1 = pos2;
pos2 = tmp;
}
Node **first_node = head;
for ( size_t i = 0; *first_node != NULL && i < pos1; i++ )
{
first_node = &( *first_node )->next;
}
success = *first_node != NULL;
if ( success )
{
Node **second_node = first_node;
for ( size_t i = 0; *second_node != NULL && i < pos2 - pos1; i++ )
{
second_node = &( *second_node )->next;
}
success = *second_node != NULL;
if ( success )
{
swap( first_node, second_node );
swap( &( *first_node )->next, &( *second_node )->next );
}
}
}
return success;
}
int main( void )
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
size_t N = sizeof( a ) / sizeof( *a );
Node *head = createLinkedList( a, N );
displayList( head );
swapFirstNode( &head, 0, 1 );
displayList( head );
swapFirstNode( &head, 2, 9 );
displayList( head );
swapFirstNode( &head, 4, 5 );
displayList( head );
}
The program output is
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
1 -> 0 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
1 -> 0 -> 9 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 2 -> null
1 -> 0 -> 9 -> 3 -> 5 -> 4 -> 6 -> 7 -> 8 -> 2 -> null
In fact it is this code snippet
if ( success )
{
swap( first_node, second_node );
swap( &( *first_node )->next, &( *second_node )->next );
}
that swaps two nodes by using the auxiliary function swap that swaps two pointers.
As you can see the function swapFirstNodeis very flexible. It can swap any two nodes of the list. And it indeed swaps two nodes not just data stored in nodes.
Pay attention to that you need to write a function that will clear the list that is that will free all the allocated memory.
I'm trying to store the values in the linked list dynamically.
I want the user to input the size of the linked List. Then based on the input I want to allocate the memory (i.e if Input : 3 then three nodes should be created).
If memory is allocated for nodes then I store the head node in a temp.
After that I want to store the data in list untill list comes to the end
The algorithm which I used is following
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
// Printing the list
void printList(struct node *ptr)
{
int i = 1;
while(ptr != NULL)
{
printf("\n Value in Node %d : %d",i ,ptr->data);
ptr = ptr->next;
i++;
}
}
int main()
{
int n;
struct node *head;
struct node *temp;
printf("\n Enter the size of linkedList : ");
scanf("%d",&n);
head = malloc(sizeof(struct node) * n);
// Storing head in temp
temp = head;
int i = 1; // Keep track on the position of the list
while(temp != NULL) // Untill temp get to end of the list
{
printf("\n Enter the value in node %d : ", i);
scanf("%d",&temp->data);
temp = temp->next; // Assinging next list address
}
printList(head);
return 0;
}
I don't understand why it printing only one value when I'm executing it.
I don't know how wrong I was?
**OUTPUT : **
$ clang dynamicList.c -o a
$ ./a
Enter the size of linkedList : 10
Enter the value in node 1 : 9
Value in Node 1 : 9
This call of malloc
head = malloc(sizeof(struct node) * n);
allocates an uninitialized memory.
Thus this statement in the while loop
temp = temp->next;
assigns an indeterminate value to the pointer temp and using this pointer further in the loop invokes undefined behavior.
Moreover the condition in the loop
while(temp != NULL) // Untill temp get to end of the list
does not make a sense.
This declaration within the block scope of the loop
int i = 1; // Keep track on the position of the list
and the similar declaration in the function printList
int i = 1;
also do not make a sense.
You need to initialize exactly n nodes. So the loop should look like
for ( int i = 0; i < n; i++ )
{
//...
}
Also you should free all the allocated memory when the list will not be needed any more.
Pay attention to that you allocated an array of nodes. Using your approach the program can look the following way.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
// Printing the list
void printList( const struct node *ptr )
{
for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
{
printf( "Value in Node %u : %d\n", i++, ptr->data );
}
}
int main( void )
{
unsigned int n = 0;
struct node *head = NULL;
printf( "Enter the size of linkedList : " );
scanf( "%u", &n );
head = malloc( n * sizeof( struct node ) );
struct node *temp = head;
for ( unsigned int i = 0; i < n; i++ )
{
printf( "Enter the value in node %u : ", i + 1 );
scanf( "%d", &temp->data );
temp->next = i == n - 1 ? NULL : temp + 1;
++temp;
}
printList( head );
free( head );
return 0;
}
The program output might look like
Enter the size of linkedList : 10
Enter the value in node 1 : 1
Enter the value in node 2 : 2
Enter the value in node 3 : 3
Enter the value in node 4 : 4
Enter the value in node 5 : 5
Enter the value in node 6 : 6
Enter the value in node 7 : 7
Enter the value in node 8 : 8
Enter the value in node 9 : 9
Enter the value in node 10 : 10
Value in Node 1 : 1
Value in Node 2 : 2
Value in Node 3 : 3
Value in Node 4 : 4
Value in Node 5 : 5
Value in Node 6 : 6
Value in Node 7 : 7
Value in Node 8 : 8
Value in Node 9 : 9
Value in Node 10 : 10
If you indeed want to organize data as a list instead of an array then the program can look the following way
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
// Printing the list
void printList( const struct node *ptr )
{
for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
{
printf( "Value in Node %u : %d\n", i++, ptr->data );
}
}
int main( void )
{
unsigned int n = 0;
struct node *head = NULL;
printf( "Enter the size of linkedList : " );
scanf( "%u", &n );
struct node *temp;
for ( unsigned int i = 0; i < n; i++ )
{
if ( i == 0 )
{
head = malloc( sizeof( struct node ) );
temp = head;
}
else
{
temp->next = malloc( sizeof( struct node ) );
temp = temp->next;
}
printf( "Enter the value in node %u : ", i + 1 );
scanf( "%d", &temp->data );
temp->next = NULL;
}
printList( head );
while ( head != NULL )
{
temp = head;
head = head->next;
free( temp );
}
return 0;
}
The program output might look as shown for the previous demonstrative program.
When you create a new node, you should allocate the next node and after that move the current node to the next one. Also, you should pay attention to the initial state (when size is 1). You should modify your code similar to this:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
// Printing the list
void printList(struct node* ptr) {
while (ptr != NULL) {
int i = 1;
printf("\n Value in Node %d : %d", i, ptr->data);
ptr = ptr->next;
}
}
int main() {
int n;
struct node* head;
struct node* temp;
printf("\n Enter the size of linkedList : ");
scanf("%d", &n);
int i = 1; // Keep track on the position of the list
while (i <= n) // Untill temp get to end of the list
{
if (i == 1) {
head = malloc(sizeof(struct node) * n);
temp = head;
} else {
temp->next = malloc(sizeof(struct node) * n);
temp = temp->next;
}
printf("\n Enter the value in node %d : ", i);
scanf("%d", &temp->data);
++i;
}
printList(head);
return 0;
}
Also, you should free dynamically allocated memory at the end of the program to avoid memory leaks.
I've got this question where I'm supposed to write a function called - "createList" that gets a linked list(without a dummy element) of ints. The function should remove every element that is bigger than the previous one and the next one.
Also, I have to make a new linked list (without a dummy element) where I place all the removed elements from the original linked list. (The elements should stay in the same order that they appeared in the original linked list).
(createlist is createListEx4() in my code)
For instance, an original linked list : 3->6->1->9->8->4->5;
would be updated to : 3->1->8->4;
The "removed elements" linked list would be: 6->9->5;
The function will return a pointer to the "removed elements" linked list
I wrote this code and I cant seem to understand how to make it work.
There is a memory leak while I print the "removed elements" linked list, and doesn't return the correct elements.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef int data_type;
typedef struct Node2
{
data_type data;
struct Node2 *next;
}Node2;
Node2 * createList2(data_type data);
Node2 * addToFirst2(Node2 *head, data_type data);
Node2 * addToLast2(Node2 *head, data_type data);
void printf_List2(Node2 *head);
void Free_List2(Node2 *head);
Node2* createListEx4(Node2 *);
void Insert_To_Big(Node2 **, int);
void delete_item(Node2 **, Node2 **);
Node2* insert_list();
void main()
{
Node2 *head = NULL;
Node2 *Odd_list = NULL;
head = insert_list(); // A Function which creates a Linked List
printf("You Entered This linked-list:\n");
printf_List2(head); // A Function which prints the Imported List
Odd_list = createListEx4(head); // a Function which Returns The address to The Odd linked list
printf("The Odd Linked-List is:\n");
printf_List2(Odd_list); // A Function Which Prints the Odd List
Free_List2(Odd_list); // Free The list After we have finished using it
}
Node2* insert_list() // A function Which imports numbers to the linked list till -1
{
int Num;
Node2 *Head = NULL;
printf("Please enter the Number you want to Sort untill -1:\n");
scanf("%d", &Num);
while (Num != -1)
{
Head = addToLast2(Head, Num); // The last entered Number will be the Head
scanf("%d", &Num);
}
return Head;
}
Node2* createListEx4(Node2 *head) // **head will be in the end the Even Linked List**
{
Node2 *Big = NULL;
Node2 *temp, *step, *prev = NULL;
if (head == NULL) // if the linked list is empty
return NULL;
if (head->data > head->next->data)
{
Insert_To_Big(&Big, head->data);
temp = head;
head = head->next;
free(temp);
}
prev = head;
// At this point we start runnig the list from an even Number //
step = head;
while (step ->next ->next != NULL)
{
if ((step->data < step->next->data) && (step->next->data > step->next->next->data))
{
Insert_To_Big(&Big, step->next->data);
delete_item(&step, &prev);
}
else
{
prev = step;
step = step->next;
}
}
if (step->data < step->next->data)
{
Insert_To_Big(&Big, step->next->data);
free(step->next);
}
step = NULL;
printf("The Even Linked-List is:\n");
printf_List2(head);
Free_List2(head);
return Big;
}
void delete_item(Node2 **step, Node2 **prev) //A Funtions Which Deletes a Node and Connects the prev Node to the Next one
{
Node2 *temp = *step;
*step = (*step)->next;
(*prev)->next = *step;
free(temp);
}
void Insert_To_Big(Node2 **head, int Num) // A Function Which Creates The Odd linked list
{
*head = addToLast2(*head, Num);
}
Node2 * createList2(data_type data)
{
Node2 *temp = (Node2*)malloc(sizeof(Node2));
temp->data = data;
temp->next = NULL;
return temp;
}
Node2 * addToFirst2(Node2 *head, data_type data)
{
Node2 *temp = createList2(data);
temp->next = head;
return temp;
}
Node2 * addToLast2(Node2 *head, data_type data)
{
Node2 *p = head;
Node2 *temp = createList2(data);
if (head == NULL)
return temp;
while (p->next != NULL)
p = p->next;
p->next = temp;
return head;
}
void printf_List2(Node2 *head)
{
Node2 *p = head;
while (p != NULL)
{
printf("%d, ", p->data);
p = p->next;
}
printf("\n\n");
}
void Free_List2(Node2 *head)
{
Node2 *temp = head;
while (temp != NULL)
{
head = head->next;
free(temp);
temp = head;
}
}
My five cents.:)
Here is a demonstrative program. I named the corresponding function split. The function is called for different corner cases.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
} Node;
void clear( Node **head )
{
while ( *head )
{
Node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
}
size_t assign( Node **head, const int a[], size_t n )
{
clear( head );
size_t count;
for ( size_t i = 0; i < n && ( *head = malloc( sizeof( Node ) ) ) != NULL; i++ )
{
( *head )->data = a[i];
( *head )->next = NULL;
head = &( *head )->next;
++count;
}
return count;
}
FILE * display( const Node *head, FILE *fp )
{
for ( ; head != NULL; head = head->next )
{
fprintf( fp, "%d -> ", head->data );
}
fputs( "null", fp );
return fp;
}
Node * split( Node **head )
{
Node *out_head = NULL;
Node **out_current = &out_head;
for ( Node *prev = NULL; *head != NULL; )
{
if ( prev != NULL || ( *head )->next != NULL )
{
if ( ( prev == NULL || prev->data < ( *head )->data ) &&
( ( *head )->next == NULL || ( *head )->next->data < ( *head )->data ) )
{
Node *tmp = *head;
*head = ( *head )->next;
tmp->next = NULL;
*out_current = tmp;
out_current = &tmp->next;
}
else
{
prev = *head;
}
}
else
{
prev = *head;
}
if ( *head != NULL ) head = &( *head )->next;
}
return out_head;
}
int main(void)
{
Node *head = NULL;
int a1[] = { 3 };
assign( &head, a1, sizeof( a1 ) / sizeof( *a1 ) );
fputc( '\n', display( head, stdout ) );
Node *head2 = split( &head );
fputc( '\n', display( head, stdout ) );
fputc( '\n', display( head2, stdout ) );
clear( &head2 );
clear( &head );
putchar( '\n' );
int a2[] = { 3, 6 };
assign( &head, a2, sizeof( a2 ) / sizeof( *a2 ) );
fputc( '\n', display( head, stdout ) );
head2 = split( &head );
fputc( '\n', display( head, stdout ) );
fputc( '\n', display( head2, stdout ) );
clear( &head2 );
clear( &head );
putchar( '\n' );
int a3[] = { 6, 3 };
assign( &head, a3, sizeof( a3 ) / sizeof( *a3 ) );
fputc( '\n', display( head, stdout ) );
head2 = split( &head );
fputc( '\n', display( head, stdout ) );
fputc( '\n', display( head2, stdout ) );
clear( &head2 );
clear( &head );
putchar( '\n' );
int a4[] = { 3, 6, 1, 9, 8, 4, 5 };
assign( &head, a4, sizeof( a4 ) / sizeof( *a4 ) );
fputc( '\n', display( head, stdout ) );
head2 = split( &head );
fputc( '\n', display( head, stdout ) );
fputc( '\n', display( head2, stdout ) );
clear( &head2 );
clear( &head );
return 0;
}
The program output is
3 -> null
3 -> null
null
3 -> 6 -> null
3 -> null
6 -> null
6 -> 3 -> null
3 -> null
6 -> null
3 -> 6 -> 1 -> 9 -> 8 -> 4 -> 5 -> null
3 -> 1 -> 8 -> 4 -> null
6 -> 9 -> 5 -> null
Your code is much more complicated than need and also contains a number of logical errors.
For instance, you shouldn't use malloc and free when moving node from one list to the other. Just change pointers.
And this part from the start of createListEx4
if (head->data > head->next->data)
{
Insert_To_Big(&Big, head->data);
temp = head;
head = head->next;
free(temp);
}
You only compare head to head->next but that's not what your requirements are saying. Further, you simply free the element but it should have been moved - not freed.
Below is an implementation you can look at. There are room for improvements but I tried to keep the code simple so that it's easy to understand.
typedef int data_type;
typedef struct node
{
data_type data;
struct node *next;
} node;
node* create_static_list(void)
{
// Bypassing check for NULL for readability - don't do it in real code
node* r = NULL;
int a[] = {5, 4, 8, 9, 1, 6, 3};
for (size_t i = 0; i < sizeof a / sizeof a[0]; ++i)
{
node* t = malloc(sizeof *t);
t->next = r;
t->data = a[i];
r = t;
}
return r;
}
void add_to_other_list(node** head, node* p)
{
static node* tail = NULL;
p->next = NULL;
if (tail == NULL)
{
*head = p;
}
else
{
tail->next = p;
}
tail = p;
}
node* remove_special(node* p)
{
node* res = NULL;
if (p == NULL) return res; // 0 elements
if (p->next == NULL) return res; // 1 element
if (p->next->next == NULL) // 2 elements
{
// Special handling of last element in list
if (p->next->data > p->data)
{
// Move p->next to other list
add_to_other_list(&res, p->next);
p->next = NULL;
return res;
}
}
// Repeat as long as the list has minimum 3 elements
while (p->next->next)
{
if ((p->next->data > p->data) &&
(p->next->data > p->next->next->data))
{
// Move p-next
node* t = p->next;
p->next = p->next->next;
add_to_other_list(&res, t);
}
p = p->next;
}
if (p->next == NULL) return res; // 1 element left, just return
if (p->next->next == NULL) // 2 elements left - check last element
{
// Special handling of last element in list
if (p->next->data > p->data)
{
// Move p->next to other list
add_to_other_list(&res, p->next);
p->next = NULL;
}
}
return res;
}
// This is OPs function (expect for variable names)
void print_list(node *p)
{
while (p != NULL)
{
printf("%d, ", p->data);
p = p->next;
}
printf("\n\n");
}
int main(void)
{
node* head = create_static_list();
print_list(head);
node* removed = remove_special(head);
print_list(head);
print_list(removed);
}
OUTPUT
3, 6, 1, 9, 8, 4, 5,
3, 1, 8, 4,
6, 9, 5,
There is no need to create new elements for the returned list. Elements removed from the original list can be moved to the returned list by manipulating the links.
An element is to be moved from the original list to the returned list if its data is bigger than all of its neighboring elements that exist. There are two special cases to consider: (1) if the original list is empty, the returned list is empty; (2) if the original list consists of a single element, move it to the returned list. (Case (2) was not explicitly stated by OP, but it seems consistent. It only affects the tests for whether an element should be moved or not, which can be changed easily.)
Since the first element can be removed from the original list the function's parameter should be a double pointer, pointing to the link to the first element of the list.
The following function implements the list processing described above:
Node2 *createListEx4(Node2 **list)
{
Node2 *bigHead = NULL; /* Head of 'big' list. */
Node2 **bigEnd = &bigHead; /* Pointer to terminating link of 'big' list. */
Node2 *prev = NULL; /* Previous element to compare data with. */
Node2 *next; /* Next element to compare data with. */
Node2 *cur; /* Current element. */
while ((cur = *list) != NULL)
{
next = cur->next;
if ((!prev || cur->data > prev->data) &&
(!next || cur->data > next->data))
{
/* Move current element to 'big' list. */
*bigEnd = cur;
bigEnd = &cur->next;
*list = next;
}
else
{
/* Skip over current element. */
list = &cur->next;
}
prev = cur;
}
/* Terminate the 'big' list. */
*bigEnd = NULL;
return bigHead;
}
Examples:
Original: (null)
Returned: (null)
Remaining: (null)
Original: 1
Returned: 1
Remaining: (null)
Original: 1 2
Returned: 2
Remaining: 1
Original: 2 1
Returned: 2
Remaining: 1
Original: 1 2 3
Returned: 3
Remaining: 1 2
Original: 1 3 2
Returned: 3
Remaining: 1 2
Original: 2 1 3
Returned: 2 3
Remaining: 1
Original: 2 3 1
Returned: 3
Remaining: 2 1
Original: 3 1 2
Returned: 3 2
Remaining: 1
Original: 3 2 1
Returned: 3
Remaining: 2 1
Can someone explain me why this code give me as result the empty list:
typedef struct str_node{
int data;
struct str_node *next;
}node;
void begin(node *head);
void display_list(node *head);
int main(){
node *head;
int i;
head = NULL;
for(i=0;i<5;i++) {
begin(head);
}
display_list(head);
return 0;
}
void begin(node *head){
node *new;
int value;
new = (node*) malloc(sizeof(node));
printf("Insert the element to add at the beginning of the list: ");
scanf("%d",&value);
new->data = value;
new->next = head;
head = new;
}
But if i change the begin() function with the pointer to pointer it gives to me the right list?
void begin(node **head){
node *new;
int value;
new = (node*) malloc(sizeof(node));
printf("Insert the element to add at the beginning of the list: ");
scanf("%d",&value);
new->data = value;
new->next = *head;
*head = new;
}
Can you also explain me why when i pass in the main the node head to the function begin i have to pass it as "&head"? and no more as "head"
In the first program in this code snippet
head = NULL;
for(i=0;i<5;i++) {
begin(head);
}
the pointer head is passed to the function begin by value. That is a copy of the value of the pointer head declared in main is created and is assigned to the parameter with the same name of the function begin
void begin(node *head);
So within the function it is the parameter head that holds initially a copy of the original pointer head that is changed. The original pointer head the value of which was assigned to the parameter is not being changed.
To change the original pointer head declared in main you have to pass it to the function by reference indirectly through a pointer to the pointer head as it is done in the second program.
So the function should be declared like
void begin(node **head);
And you have to pass the pointer head indirectly through a pointer to it
begin( &head );
In this case dereferencing the passed pointer the function will get a direct access to the original pointer head declared in main and can change it (not a copy of its value as it takes place in the first function definition)
new->next = *head;
*head = new;
To make it more clear consider this simple demonstrative program.
#include <stdio.h>
typedef int T;
void f( T t )
{
t = 10;
}
int main(void)
{
T t = 0;
printf( "Before calling f t is equal to %d\n", t );
f( t );
printf( "After calling f t is equal to %d\n", t );
return 0;
}
Its output is
Before calling f t is equal to 0
After calling f t is equal to 0
As the function f deals with a copy of the value of the passed argument the value of the variable t declared in main was not changed.
So you need to pass the original variable t by reference through pointer like
#include <stdio.h>
typedef int T;
void f( T *t )
{
*t = 10;
}
int main(void)
{
T t = 0;
printf( "Before calling f t is equal to %d\n", t );
f( &t );
printf( "After calling f t is equal to %d\n", t );
return 0;
}
Now the program output is
Before calling f t is equal to 0
After calling f t is equal to 10
In these demonstrative programs the name T is used as an alias for the type int and in main the object t has this type.
Let's now assume that the name T is an alias for the type int *.
typedef int * T;
In this case a declaration in main as for example
T t = NULL;
means that the variable t has the pointer type int *. That is it is equivalent to
int * t = NULL;
So to pass it to a function that must change the original variable t we need to pass it by reference like
f( &t );
that means that the corresponding function shall have the parameter type declared like
void f( T *t );
but as T is an alias for int * hence it means that the function has a parameter of the type int **.
void f( int * *t );
Because head is (effectively) a local variable, so changing it has no effect outside of the function, whereas changing *head changes what head points to, and thus does.
If you wanted a function to be able to change the value in an int variable (say, x), you would pass it a pointer to x, which would have the type int* and you would get the pointer to x by using &x. The same holds no matter what type x is.
A bit of confusion may come from declaring
node *head;
instead of
node* head;
You are declaring head. head is the variable and it is a pointer. It is not a node. Note also that a node is not a linked list: a linked list is a collection of nodes and possibly something else in order to have an useful implementation. More on this later at the end.
Fact is you have in main() declared head, just a node*. The node itself does not even exist yet. You declared begin() as
void begin(node *head);
and I think you will see it more clearly as
void begin(node* parameter);
parameter is node*.
Inside begin() you get a copy of the pointer and changing the pointer will not change the original pointer in main().
In your case it will in main() forever point to NULL.
What matters is that a pointer is like any variable: A pointer has an address. And a content. When you pass by value, just like you did, the pointer in begin() starts with NULL, the VALUE that came from main(). But the bond between them ends int the call: the initial value.
When you pass a pointer to begin(), using the operator 'address of' and writing &head things change: you will change it using the operator '*' meaning that you will change the address it points to, so it will change in main(). Since head is node* a pointer to it will be declared as node**
But consider changing the declaration of begin() for a linked list using:
node* begin(node* node);
The logic is that inserting a node can change the head of the list, so you return the new address, as in
node* _insert_begin(int value, node* pNode)
{
node* new = (node*)malloc(sizeof(node));
new->data = value;
new->next = pNode;
return new;
}
is a common way to write this. Another is to use node**.
The way I am describing here, any operation that can change the head of the list must
return the new head
receive and update a pointer to the pointer of the head
See again this code that inserts at the beginning of the list:
node* _insert_begin(int value, node* pNode)
{ // insert 'value' at the start of the list
node* new = (node*)malloc(sizeof(node));
(*new).data = value;
new->next = pNode;
return new;
}
returning new you get head updated. And you can write in main()
node* another = NULL;
display_list(another);
// inserts 5 to 0 at the beginning
for (int i = 5; i >= 0; i -= 1)
another = _insert_begin(i, another);
printf("inserted 5..0 at the beginning\n");
display_list(another);
Note the line another = _insert_begin(i, another); and you see how the pointer in main() gets updated.
This is the output
empty list
inserted 5..0 at the beginning
0 1 2 3 4
5
list has 6 elements
Using this implementation of display_list(), that prints 5 values per line:
int display_list(node* p)
{
if (p == NULL)
{
printf("empty list\n");
return 0;
};
int count = 0;
// not empty
do
{
printf("%8d ", p->data);
count++;
if (count % 5 == 0) printf("\n");
p = p->next;
} while (p != NULL);
if (count % 5 != 0) printf("\n");
printf("list has %d elements\n", count);
return count;
};
Another example: inserting at the end
note that inserting at the end can also change the head, in the case that the list is empty, so we still need to return the head address
node* _insert_end(int value, node* pNode)
{ // insert value at the end of the list
node* new = (node*)malloc(sizeof(node));
new->data = value;
new->next = NULL;
if (pNode == NULL) return new;
node* p = pNode;
while (p->next != NULL) p = p->next;
p->next = new;
return pNode;
}
Another use: inserting in ascending order
Sure, inserting in ascending order can also change the head, as in
node* _insert_ordered(int value, node* pNode)
{ // insert value at ascending order in the list
node* new = (node*)malloc(sizeof(node));
new->data = value;
new->next = NULL;
if (pNode == NULL) return new;
node* p = pNode;
node* prev = NULL; // previous node: list if forward only
while (p->next != NULL)
{
if (new->data < p->data)
{
// insert before first greater than value
if (prev == NULL)
{
// new head
new->next = p;
return new;
}; // if()
prev->next = new;
new->next = p;
return pNode; // no change in head
};
prev = p; p = p->next; // updates pointers
}; // while()
// we are at the end: new will be the last?
if (new->data < p->data)
{
if (prev == NULL)
pNode = new;
else
prev->next = new;
new->next = p;
}
else
{
p->next = new;
};
return pNode;
} // _insert_ordered()
Deleting a list
Delete a list should also return a node* in order to invalidade the head pointer. It is usual. As you get used to the mechanic of it this ensures that an invalid pointer does not remain around.
Note that this logic is cooperative: you must assign the head pointer back at every call that can change the head
node* delete_list(node* H)
{
if (H == NULL) return NULL;
if (H->next == NULL)
{ // single node
free(H);
return NULL;
};
// more than one node
do
{ node* p = H->next;
free(H);
H = p;
} while (H != NULL);
return NULL;
};
A running program
Output of the example program
empty list
inserted 5..0 at the beginning
0 1 2 3 4
5
list has 6 elements
inserted 6 to 10 at the end
0 1 2 3 4
5 6 7 8 9
10
list has 11 elements
inserted 0 to 10, ordered
0 0 1 1 2
2 3 3 4 4
5 5 6 6 7
7 8 8 9 9
10 10
list has 22 elements
inserted -1 to -10, ordered
-10 -9 -8 -7 -6
-5 -4 -3 -2 -1
0 0 1 1 2
2 3 3 4 4
5 5 6 6 7
7 8 8 9 9
10 10
list has 32 elements
inserted 11 to 20, ordered
-10 -9 -8 -7 -6
-5 -4 -3 -2 -1
0 0 1 1 2
2 3 3 4 4
5 5 6 6 7
7 8 8 9 9
10 10 11 12 13
14 15 16 17 18
19 20
list has 42 elements
about to delete list
empty list
The example C program
#include <stdio.h>
#include <stdlib.h>
typedef struct str_node
{
int data;
struct str_node* next;
} node;
void begin(node* pNode);
node* delete_list(node*);
int display_list(node*);
node* _insert_begin(int, node*);
node* _insert_end(int, node*);
node* _insert_ordered(int, node*);
int main()
{
node* another = NULL;
display_list(another);
// insert 5 to 0 at the beginning
for (int i = 5; i >= 0; i -= 1)
another = _insert_begin(i, another);
printf("inserted 5..0 at the beginning\n");
display_list(another);
// insert 6 to 10 at the end
for (int i = 6; i <= 10; i += 1)
another = _insert_end(i, another);
printf("inserted 6 to 10 at the end\n");
display_list(another);
// insert 0 to 10 ordered
for (int i = 0; i <=10; i += 1)
another = _insert_ordered(i, another);
printf("inserted 0 to 10, ordered\n");
display_list(another);
// insert -1 to -10 ordered
for (int i = -1; i >= -10; i -= 1)
another = _insert_ordered(i, another);
printf("inserted -1 to -10, ordered\n");
display_list(another);
// insert 11 to 20 ordered
for (int i = 11; i <= 20; i += 1)
another = _insert_ordered(i, another);
printf("inserted 11 to 20, ordered\n");
display_list(another);
printf("about to delete list\n");
another = delete_list(another);
display_list(another);
return 0;
}
node* delete_list(node* H)
{
if (H == NULL) return NULL;
if (H->next == NULL)
{ // single node
free(H);
return NULL;
};
// more than one node
do
{ node* p = H->next;
free(H);
H = p;
} while (H != NULL);
return NULL;
};
node* _insert_begin(int value, node* pNode)
{ // insert 'value' at the start of the list
node* new = (node*)malloc(sizeof(node));
(*new).data = value;
new->next = pNode;
return new;
}
node* _insert_end(int value, node* pNode)
{ // insert value at the end of the list
node* new = (node*)malloc(sizeof(node));
new->data = value;
new->next = NULL;
if (pNode == NULL) return new;
node* p = pNode;
while (p->next != NULL) p = p->next;
p->next = new;
return pNode;
}
node* _insert_ordered(int value, node* pNode)
{ // insert value at ascending order in the list
node* new = (node*)malloc(sizeof(node));
new->data = value;
new->next = NULL;
if (pNode == NULL) return new;
node* p = pNode;
node* prev = NULL; // previous node: list if forward only
while (p->next != NULL)
{
if (new->data < p->data)
{
// insert before first greater than value
if (prev == NULL)
{
// new head
new->next = p;
return new;
}; // if()
prev->next = new;
new->next = p;
return pNode; // no change in head
};
prev = p; p = p->next; // updates pointers
}; // while()
// we are at the end: new will be the last?
if (new->data < p->data)
{
if (prev == NULL)
pNode = new;
else
prev->next = new;
new->next = p;
}
else
{
p->next = new;
};
return pNode;
} // _insert_ordered()
int display_list(node* p)
{
if (p == NULL)
{
printf("empty list\n");
return 0;
};
int count = 0;
// not empty
do
{
printf("%8d ", p->data);
count++;
if (count % 5 == 0) printf("\n");
p = p->next;
} while (p != NULL);
if (count % 5 != 0) printf("\n");
printf("list has %d elements\n", count);
return count;
};
An arguably more useful Linked List structure
Consider the following
struct no
{
void* item;
struct no* next;
struct no* prev;
}; // no
typedef struct no Node;
typedef struct
{ // example, more flexible
char* name;
unsigned size;
unsigned capacity;
Node* head;
Node* tail;
} Linked_list;
This way a linked list is defined as a container of nodes.
It has even an optional name.
size is always available and up to date
a size limit can be implement as capacity
insert at the end and at the beginning does no require you to follow all other nodes, since the list encapsulates pointers to both head and tail
a node has pointers to next AND previous nodes so some data such as playlists or collections like that can be iterated more easily.
a program can have any number of lists since each one encapsulates all of this metadata.
a list can contains anything since the data is a pointer to void, void*
functions like empty() or size() can be implemented easily
all functions use a pointer to the list
Linked_list ll_one;
Linked_list many_ll[20];
Linked_list* pLL = &ll_one;
regarding:
void begin(node *head){
Changing head only changes the call stack 'head', what is needed is to change where 'head' in the caller's function points to. TO do that, the caller must pass the address of 'head'. The fact that 'head' is,itself, a pointer doesn't help with the clarity of what needs to be done,
I'm writing a program to reverse a linked list in C. While debugging code in gdb, after the second iteration of while loop, function,reverse, take exit.
#include <stdio.h>
#include <stdlib.h>
void insert (int number);
void print ();
struct Node {
int data;
struct Node *link;
} head, *last_node;
int count (struct Node *);
void reverse (struct Node *);
int main () {
int number, choice = 0;
while (choice != 4) {
printf ("\nChoose the action: ");
printf ("\n 1. Insert ");
printf ("\n 2. Print List ");
printf ("\n 3. Reverse");
printf ("\n 4. Exit \n");
scanf("%d", &choice);
switch (choice) {
case 1 : printf ("\nEnter number to be inserted: ");
scanf ("%d", &number);
insert (number);
break;
case 2 : printf ("\nHere is/are linked list element/s: ");
print();
break;
case 3 : printf ("\nLinked List Reversed ");
reverse(&head);
break;
case 4 :
default: exit(0);
}
}
}
void insert (int number) {
if (head.data == 0) {
head.data = number;
head.link = NULL;
last_node = &head;
} else {
struct Node *new_node;
new_node = (struct Node *) malloc (sizeof(struct Node));
new_node -> data = number;
new_node -> link = NULL;
last_node -> link = new_node;
last_node = new_node;
}
}
void print () {
struct Node *start;
start = &head;
do {
printf ("%d ", start->data);
start = start->link;
} while (start != NULL);
printf ("\n");
}
void reverse (struct Node *start) {
struct Node *temp1 = NULL, *temp2;
while (start->link != NULL) {
temp2 = start->link;
start->link = temp1;
temp1 = start;
start = temp2;
}
}
After running reverse function only first element of linked list shows.
There are several drawbacks of your approach.
The first one is that it is a bad idea to declare a global variable start.
struct Node {
int data;
struct Node *link;
} head, *last_node;
Also if it is a singly-linked list then nodes should be inserted to the beginning of the list. So the global pointer last_node is not required.
The function reverse deals with the local variable start because function parameters are local variables of functions
void reverse (struct Node *start)
The original pointer to the start node is not changed in the function because the function deals with its copy.
And the function has to check whether the passed argument is already equal to NULL.
There is a simple logic behind the reverse algorithm.
You should just insert already existent nodes as if you would do this within the function that pushes new nodes into list.
And the pointer to the start node (head) must be passed by reference using a pointer to it.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *link;
};
int push_front( struct Node **head, int data )
{
struct Node *current = malloc( sizeof( struct Node ) );
int success = current != NULL;
if ( success )
{
current->data = data;
current->link = *head;
*head = current;
}
return success;
}
void output( struct Node *head )
{
for ( ; head != NULL; head = head->link )
{
printf( "%d -> ", head->data );
}
puts( "NULL" );
}
void reverse( struct Node **head )
{
struct Node *current = *head;
*head = NULL;
while ( current != NULL )
{
struct Node *tmp = current;
current = current->link;
tmp->link = *head;
*head = tmp;
}
}
int main(void)
{
struct Node *head = NULL;
const int N = 10;
for ( int i = 0; i < N; i++ ) push_front( &head, i );
output( head );
reverse( &head );
output( head );
return 0;
}
Its output is
9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> NULL
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> NULL
Of course you need to append the list implementation with a function that deletes all nodes of the list when it is not anymore required.