why insertion is not working in my link-list - c

I am learning linked list Here, I am trying to add node at the first so, I made a structure function to add but i dont know why its not working its only giving this output without adding
7
11
66
After insretion
7
11
66
and also please tell me is there any way to insert element on linked list.
// inserting element on first
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node * next;
};
void link_list_tranversal(struct Node *ptr){
while (ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
int main(){
struct Node*head;
struct Node*second;
struct Node*third;
head =(struct Node *) malloc(sizeof(struct Node));
second =(struct Node *) malloc(sizeof(struct Node));
third =(struct Node *) malloc(sizeof(struct Node));
// linking first and secend node
head ->data=7;
head->next=second;
// linking secend and third node
second->data=11;
second->next=third;
// terminate the list at the third
third->data=66;
third->next=NULL;
link_list_tranversal(head);
insert_at_first(head,56);
printf("After insretion\n ");
link_list_tranversal(head);
return 0;
}

After insert_at_first(head,56);, you've created a new node, but head is now pointing to the second node in the list and you have lost track of the newly created node. Simplest fix is to do: head = insert_at_first(head,56);. You can also pass &head and let the function update head.

You need to update the pointer you are storing in head after calling insert_at_first.
// inserting element on first
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node * next;
};
void link_list_tranversal(struct Node *ptr){
while (ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
int main(){
struct Node*head;
struct Node*second;
struct Node*third;
head =(struct Node *) malloc(sizeof(struct Node));
second =(struct Node *) malloc(sizeof(struct Node));
third =(struct Node *) malloc(sizeof(struct Node));
// linking first and secend node
head ->data=7;
head->next=second;
// linking secend and third node
second->data=11;
second->next=third;
// terminate the list at the third
third->data=66;
third->next=NULL;
link_list_tranversal(head);
head = insert_at_first(head,56);
printf("After insretion\n ");
link_list_tranversal(head);
return 0;
}
Output:
7
11
66
After insretion
56
7
11
66

A common approach when learning is to add more code and then add more.
Below is the equivalent to your entire program, but done with far fewer lines of code (but lots of comments.)
Please read this and think about what and why of each line.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node { // Using 'typedef' saves LOTS of typing (and reading)
int data; // for now, just one integer
struct Node *next;
} node_t; // conventional naming of a 'type' with "_t" suffix
int mmain() {
int data[] = { 66, 11, 7, 56 }; // your data in compact form
node_t *head = NULL; // ALWAYS initialise variable. Don't let random values happen
for( int i = 0; i < sizeof data/sizeof data[0]; i++ ) { // loop to create LL
// use 'calloc()'. explained below
// do not cast the return pointer from malloc/calloc
node_t *pn = calloc( 1, sizeof *pn );
// malloc/calloc can fail. Halt processing immediately.
if( pn == NULL ) {
fprintf( stderr, "panic! calloc failed.\n" );
exit( 1 );
}
pn->data = data[i]; // for now, just one integer
pn->next = head; // two lines of code "prepend" the new node
head = pn;
// traverse here showing growth
for( pn = head; pn; pn = pn->next )
printf( "%d ", pn->data );
putchar( '\n' );
}
// Avoid memory leaks
// Don't forget to release heap memory when no longer needed.
while( head ) {
node_t *pn = head; // node to be free'd
head = head->next; // remember next
free( pn ); // OFF WITH ITS HEAD!
}
return 0;
}
Output
66
11 66
7 11 66
56 7 11 66
I recommend using calloc() over malloc() when developing code that will grow.
Right now the payload carried by each node is a single integer.
In the thick of it, it is possible to add more elements to the node structure (bigger payload)
yet omit setting every one of the new elements to a known value.
Using calloc() insures that all bytes will consistently be initialised to null.
Then, when testing, you get consistent behaviour (working or not), making it easier to track down bugs.
Notice that "prepending" to a LL is too trivial an operation to "break out" to its own function. "Appending" is not much more difficult, but may justify a function according to your tastes.
Here is the same code again, without comments, for comparison.
typedef struct Node {
int data;
struct Node *next;
} node_t;
int main() {
int data[] = { 66, 11, 7, 56 };
node_t *head = NULL;
for( int i = 0; i < sizeof data/sizeof data[0]; i++ ) {
node_t *pn = calloc( 1, sizeof *pn );
if( pn == NULL ) {
fprintf( stderr, "panic! calloc failed.\n" );
exit( 1 );
}
pn->data = data[i];
pn->next = head;
head = pn;
// traversal for debugging
for( pn = head; pn; pn = pn->next )
printf( "%d ", pn->data );
putchar( '\n' );
}
while( head ) {
node_t *pn = head;
head = head->next;
free( pn );
}
return 0;
}
Even if the program creates new nodes at different locations, you must consider the payload. Don't write a trivial insert() function that adjusts two pointers but receives 27 parameters in the function call.

The function insert_at_first returns a new value of the pointer that points to the head node. You need to assign the returned value to the pointer head to update it
head = insert_at_first(head,56);
Also there is no great sense to allocate nodes in main when you already have the function insert_at_first
You could initially write for example
struct Node *head = NULL;
head = insert_at_first( head, 66 );
head = insert_at_first( head, 11 );
head = insert_at_first( head, 7 );
head = insert_at_first( head, 56 );
Also as the function link_list_tranversal does not change the outputted list then its parameter should be declared with qualifier const
void link_list_tranversal( const struct Node *ptr );
Pay attention to that this function definition
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
is not good because the function will invoke undefined behavior if memory for a node will not allocated successfully.
It is better to declare and define the function the following way
int insert_at_first( struct Node **head, int data )
{
struct Node *ptr = malloc( *ptr );
int success = ptr != NULL;
if ( success )
{
ptr->next = *head;
ptr->data = data;
*head = ptr;
}
return success;
}
And the function can be called like for example
struct Node *head = NULL;
insert_at_first( &head, 66 );
or
struct Node *head = NULL;
if ( !insert_at_first( &head, 66 ) )
{
puts( "Error. No enough memory" );
}

Related

Why does theis recursive function not work?

I am trying to write a recursive function to reverse a doubly linked list. This code is not complete yet but I am hit with a issue. The application is not executing completely.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct nodes
{
uint8_t x;
struct nodes *next;
struct nodes *prev;
}Node;
Node *head = NULL;
void rev_rec_dll(Node **a, Node **b)
{
//check if it is last node in the list
if((*a)->next != NULL)
{
//set next to prev and prev to next
(*a)->next = (*a)->prev;
(*a)->prev = (*b);
printf("done for node %d and moving on..\n", ((*a)->x));
//recursive call by passing next two nodes
rev_rec_dll(b, &((*b)->next));
}
else
{
printf("reached new head\r\n");
head = (*a);
}
}
void add_node(Node **h_node, uint8_t x)
{
//check if there is at least one node in the list and if not add first node
if((*h_node) == NULL)
{
*h_node = (Node *)malloc(sizeof(Node));
(*h_node)->x = x;
(*h_node)->next = NULL;
(*h_node)->prev = NULL;
}
else
{
Node *temp = *h_node;
//get the last node
while(temp->next != NULL)
{
temp = temp->next;
}
//add new node
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->x = x;
newNode->next = NULL;
newNode->prev = temp;
temp->next = newNode;
}
}
void display_nodes(Node *h_node)
{
while(h_node != NULL)
{
printf("Node: %u\n", h_node->x);
h_node = h_node->next;
}
}
int main(int argc, char **argv)
{
//add three nodes
add_node(&head, 1);
add_node(&head, 2);
add_node(&head, 3);
//display nodes
display_nodes(head);
//add three more nodes
add_node(&head, 4);
add_node(&head, 5);
add_node(&head, 6);
//display all 6 nodes
display_nodes(head);
//reverse the linked list
rev_rec_dll(&head, &(head->next));
//display reversed nodes
display_nodes(head);
return 0;
}
The output of the program is given below:
Node: 1
Node: 2
Node: 3
Node: 1
Node: 2
Node: 3
Node: 4
Node: 5
Node: 6
done for node 1 and moving on..
I want to know what is wrong in the function rev_rec_dll(). Also, I want to know if the way I am passing the arguments to this function is correct or not. If it is not correct please provide appropriate reason on why it is wrong. The arguments passed to rev_rec_dll function is current node and next node in the linked list.
The reversing logic may not be accurate but I want to know if the way the arguments are passed is correct. Why does it exit in the middle? A memory violation?
For starters it is a bad idea to declare the pointer to head node as a file scope variable and when the functions depend on the file scope variable.
Node *head = NULL;
You should move this declaration inside the function main and correspondingly rewrite your functions.
Also the structure declaration will look better if to declare it like
typedef struct Node
{
uint8_t x;
struct Node *next;
struct Node *prev;
} Node;
Otherwise the names nodes and Node will only confuse readers of the code.
There are two problems with the function. The first one is that initially the second function argument points to the data member next of the head node
rev_rec_dll(&head, &(head->next));
that is changed within the function in the compound statement of the if statement.
To make it clear consider a list that contains only two nodes
| NULL <- 1 -> 2 | <-> | 1 <- 2 -> NULL|
Inside the first recursive call of the function there are executed the following statements
(*a)->next = (*a)->prev;
(*a)->prev = (*b);
Again pay attention to that the function is called like
rev_rec_dll(&head, &(head->next));
That is the parameter b of the function points to the data member next of the head node and the first of the above statements changes the value of the data member
(*a)->next = (*a)->prev;
So now the expression *b yields data member next that now contains the value of the data member prev (in this case NULL).
In fact you have
(*a)->next = (*a)->prev;
(*a)->prev = ( *a )->next; //(*b);
because the expressions ( *a )->next and *b are equivalent due to initializations of parameters by argument expressions.
That is the both data members. next and prev, get the initial value of the data member prev and you have
| NULL <- 1 -> NULL | <- | 1 <- 2 -> NULL|
Then the function is called like
rev_rec_dll(b, &((*b)->next));
that invokes undefined behavior because the expression *b yields a null pointer.
Another problem is that in this code snippet
else
{
printf("reached new head\r\n");
head = (*a);
}
data members prev and next of the last node in the list are not changed because the control is bypassed the compound statement of the if statement
And moreover your function will invoke undefined behavior if it will
be called for an empty list.
The function should be declared with only one parameter like for example
void rev_rec_dll( Node **head );
Here is a demonstration program that shows how the recursive function that reverses the list can be implemented.
In the demonstration program there is not used a file scope pointer to the head node. In this case within a program you will be able to define multiple lists.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct Node
{
uint8_t x;
struct Node *next;
struct Node *prev;
} Node;
void clear( Node **head )
{
while (*head)
{
Node *current = *head;
*head = ( *head )->next;
free( current );
}
}
size_t assign( Node **head, const uint8_t *a, size_t n )
{
clear( head );
size_t cnt = 0;
for ( Node *prev = NULL; n-- && ( *head = malloc( sizeof( Node ) ) ) != NULL; cnt++)
{
( *head )->x = *a++;
( *head )->next = NULL;
( *head )->prev = prev;
prev = *head;
head = &( *head )->next;
}
return cnt;
}
void rev_rec_dll( Node **head )
{
if ( *head )
{
Node *tmp = ( *head )->next;
( *head )->next = ( *head )->prev;
( *head )->prev = tmp;
if (( *head )->prev != NULL)
{
*head = ( *head )->prev;
rev_rec_dll( head );
}
}
}
void display_nodes( const Node *head )
{
for (; head != NULL; head = head->next)
{
printf( "%" PRIu8 " -> ", head->x );
}
puts( "null" );
}
int main( void )
{
Node *head = NULL;
uint8_t a[] = { 1, 2, 3, 4, 5, 6 };
assign( &head, a, sizeof( a ) / sizeof( *a ) );
display_nodes( head );
rev_rec_dll( &head );
display_nodes( head );
clear( &head );
}
The program output is
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null
There's no real point of using pointer to a pointer in rev_rec_dll(Node **a, Node **b), i would suggest you read into practical implications of pointers to pointers
What you can do here is just use regular pointers like so:
void rev_rec_dll(Node* a, Node* b)
{
//check if it is last node in the list
if(a->next != NULL)
{
//set next to prev and prev to next
a->next = a->prev;
a->prev = b;
printf("done for node %d and moving on..\n", a->x);
//recursive call by passing next two nodes
rev_rec_dll(b, b->next);
}
else
{
printf("reached new head\r\n");
head = a;
}
}
then in main function call it like so
rev_rec_dll(head, head->next);
also, as Vlad mentioned you shouldn't use two parameters in this function, it adds unnecessary complexity as well as makes it a bit harder to track if you pass and use NULL in the future.
also also, it's best that you learn how to use debugger now to see where things hit the fan clearly.

linked list problem when displaying the list in C

having segmentation error while trying to access nodes
i can create new nodes with my add function after function executes i cant access my nodes. i think they deallocated in memory but i couldnt figure it out.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *nextNode;
};
struct node *head;
void add(int data)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
new->data = data;
new->nextNode = NULL;
struct node *temp1;
temp1 = head;
while (temp1 != NULL)
{
temp1 = temp1->nextNode;
}
temp1 = new;
printf("\nValue of temp1:%d\nValue of new: %d\n",temp1,new);
printf("\nData of temp1:%d\nData of new:%d\n",temp1->data,new->data);
}
void printList()
{
int i = 1;
struct node *tempP;
tempP = head;
while (tempP != NULL)
{
printf("\nData of %dth element is : %d\n", i, tempP->data);
tempP = tempP->nextNode;
i++;
}
}
void main()
{
head = (struct node *)malloc(sizeof(struct node));
head->data = 10;
head->nextNode = NULL;
add(20);
add(30);
add(40);
printList();
}
This code snippet within the function add
struct node *temp1;
temp1 = head;
while (temp1 != NULL)
{
temp1 = temp1->nextNode;
}
temp1 = new;
is wrong. Within it there is changed the local variable temp1. It is not linked with the list.
Also using the conversion specifier %d to output a pointer invokes undefined behavior. You should use conversion specifier %p.
Using your approach to the function definition you could write instead.
void add(int data)
{
struct node *new = malloc( sizeof( *new ) );
new->data = data;
new->nextNode = NULL;
if ( head == NULL )
{
head = new;
}
else
{
struct node *temp1 = head;
while ( temp1->nextNode != NULL)
{
temp1 = temp1->nextNode;
}
temp1->nextNode = new;
}
printf("\nValue of temp1->nextNode:%p\nValue of new: %p\n",
( void * )temp1->nextNode, ( void * )new);
printf("\nData of temp1->nectNode:%d\nData of new:%d\n",
temp1->nextNode->data,new->data);
}
Pay attention to that it is a bad design when functions depend on a global variable as in your case where the functions depend on the global variable head.
And it is also a bad idea when the first node is added to the list bypassing the function add.
And you need check whether a node was successfully allocated.
Also according to the C Standard the function main without parameters shall be declared like
int main( void )
As for me I would declare the pointer to the head node in main like
int main( void )
{
struct node *head = NULL;
// ...
And the function add will look like
int add( 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->nextNode = NULL;
while ( *head != NULL ) head = &( *head )->nextNode;
*head = new_node;
}
return success;
}
and called like
struct node *head = NULL;
add( &head, 10 );
add( &head, 20 );
add( &head, 30 );
add( &head, 40 );
In turn the function printList can look like
void printList( const struct node *head )
{
for ( size_t i = 1; head != NULL; head = head->nextNode )
{
printf( "Data of %zuth element is : %d\n", i++, head->data);
}
}
And you need at least to write one more function that will free all the allocated memory.
There were a handful of mistakes in your add() function, which I've highlighted and fixed below:
void add(int data)
{
struct node *new = malloc(sizeof(*new)); // suggested by ryyker
new->data = data;
new->nextNode = NULL;
struct node *temp1 = head; // just keep it short
while (temp1->nextNode != NULL) // temp1 != NULL will always result in it being NULL, last node is the node with NULL as next
{
temp1 = temp1->nextNode;
}
temp1->nextNode = new; // you want the next in the list to be the new node, not reassign the head to a new node. That's a memory leak.
// remember: temp1 == head, and head = new makes head lose the original node and point to the newly created one
printf("\nValue of temp1:%p\nValue of new: %p\n",temp1,new); // %p for pointers
printf("\nData of temp1:%d\nData of new:%d\n",temp1->data,new->data);
}
Output:
Value of temp1:0x55809a4b22a0
Value of new: 0x55809a4b22c0
Data of temp1:10
Data of new:20
Value of temp1:0x55809a4b22c0
Value of new: 0x55809a4b26f0
Data of temp1:20
Data of new:30
Value of temp1:0x55809a4b26f0
Value of new: 0x55809a4b2710
Data of temp1:30
Data of new:40
Data of 1th element is : 10
Data of 2th element is : 20
Data of 3th element is : 30
Data of 4th element is : 40

Function to insert a node in a linked list in C

I'm trying to learn data structures in C and I'm stuck at the first function I made.
If I run this nothing happens.
I get no errors but the program doesn't print anything.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
void insert(int data, node *head){
node *new_node = malloc(sizeof(node));
new_node->data = data;
head = new_node;
}
int main(){
node *head = NULL;
insert(8, head);
printf("head.data: %d\n", head->data);
}
But if I put the code from the function insert in the main function it works.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
int main(){
node *head = NULL;
node *new_node = malloc(sizeof(node));
new_node->data = 5;
head = new_node;
printf("head.data: %d\n", head->data);
}
Do I not know how to use functions in C or what is the problem with my first code?
In this call
insert(8, head);
the pointer head is passed to the function by value.
It means that the function deals with a copy of the value of the pointer.
Changing the copy within the function does not reflect on the original value of the pointer.
Either you need to pass the pointer by reference through a pointer to it or to return the new value of the pointer from the function and to assign it to the original pointer.
Also you forgot to set the data member next of the created node to NULL or more precisely to head.
Here you are.
int insert( node **head, int data )
{
node *new_node = malloc( sizeof( node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
and the function is called like
insert( &head, 8 );
or
if ( !insert( &head, 8 ) )
{
puts( "Error: not enough memory." );
}
Another approach is to return the new value of the pointer head from the function.
For example
node * insert( node *head, int data )
{
node *new_node = malloc( sizeof( node ) );
if ( new_node != NULL )
{
new_node->data = data;
new_node->next = head;
}
return new_node;
}
In this case you need to use the function with caution.
For example
node *tmp = insert( head, 8 );
if ( tmp != NULL )
{
head = tmp;
}
else
{
puts( "Error: not enough memory." );
}
The variable head in main and the variable head in insert are two different variables. When in insert you assign something to that local variable, it does not affect the variable head in main.
You can solve this in different ways. One is to pass the address of head to the function, so insert can actually modify what is at that address:
Not your question, but you should also initialise the next member of new_node:
void insert(int data, node **headPtr){
node *new_node = malloc(sizeof(node));
new_node->data = data;
new_node->next = *headPtr;
*headPtr = new_node;
}
int main(){
node *head = NULL;
insert(8, &head);
printf("head.data: %d\n", head->data);
}

Add to list function

I'm trying to write a function that inserts node at the end of the list.
The problem is that the pointer of the last node of the list doesn't point to NULL and if I show the list I get an error from the system.
struct node{
int value;
struct node *next;
};
struct node *AddToList (struct node *list, int n);
int main()
{
struct node *node;
node = AddToList(node, 30);
node = AddToList(node, 20);
node = AddToList(node, 10);
showlist(node);
return 0;
}
struct node *AddToList (struct node *list, int n){
struct node *new_node;
new_node=malloc(sizeof(struct node));
new_node->value=n;
new_node->next=list;
return new_node;
};
Yes that's because first node that you insert - it's next is not having the value NULL.
struct node *node = NULL; //<------
node = AddToList(node, 30);
node = AddToList(node, 20);
node = AddToList(node, 10);
showlist(node);
This will solve the problem. Now as a result of doing this - the very first time you insert the node, it's next will be assigned the value NULL. Because for the first call to AddToList the list is NULL.
The way you did it - node was containing some indeterminate value (garbage value)(node is a variable with automatic storage duration) and then this is added as link to the first node. This is of no practical use because now you can't traverse the list thinking that you will find a NULL value which is when you should stop.
From standard chapter ยง6.7.9
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
You should check the return value of malloc. In case it fails - you should handle that case. And free the dynamically allocated memory when you are done working with it.
Also not sure how did you try to show the list, but if it is with the assumption that last node will point to NULL then started looping over it - then you have earned a Undefined behavior in your code.
'm trying to write a function that inserts node at the end of the
list.
This function
struct node *AddToList (struct node *list, int n){
struct node *new_node;
new_node=malloc(sizeof(struct node));
new_node->value=n;
new_node->next=list;
return new_node;
};
does not insert a node at the end of the list. It inserts a node at the beginning of the list before the head node.
The function that inserts a node at the end of the list can look the following way.
int AddToList ( struct node **list, int n )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = n;
new_node->next = NULL;
while ( *list != NULL ) list = &( *list )->next;
*list = new_node;
}
return success;
}
And the function can be called like
struct node *head = NULL;
AddToList( &head, 10);
AddToList( &head, 20);
AddToList( &head, 30);
if you want that the order of the values of the list would be 10, 20, 30.
The problem is that the pointer of the last node of the list doesn't
point to NULL
Because new nodes are inserted before the first node that was not initialized
struct node *node;
and hence has an indeterminate value the last node in the list does not point to NULL.
You have to set the initial pointer to NULL.
struct node *node = NULL;
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )
when the user wants to add node at the last first check if it is empty list if so means add the new node as head node.if the list is not empty travese the list and find out the last node by checking tp->next=NULL then store the address of new node in tp->next and make the new node's next field with NULL.the following program show the concept clearly
#include<stdio.h>
#include<malloc.h>
int item,count,pos;
struct node
{
int info;
struct node *next;
}*head,*tp;
void traversal()
{
if(head==NULL)
printf("\n List is empty");
else
{
tp=head;
while(tp->next!=NULL)
{
printf("\n%d",tp->info);
tp=tp->next;
}
printf("\n%d",tp->info);
}
}
void insertlast()
{
struct node *temp;
temp=(struct node*) malloc(sizeof(temp));
printf("\nEnter the element:");
scanf("%d",&item);
temp->info=item;
temp->next=NULL;
if(head==NULL)
head=temp;
else
{
tp=head;
while(tp->next!=NULL)
{
tp=tp->next;
}
tp->next=temp;
}
}
int main()
{
printf("\n\t\t**********SINGLY LINKED LIST********");
printf("\n\t------------------------------------------------------");
printf("\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
return 0;
}
Output
**********SINGLY LINKED LIST********
------------------------------------------------------
Insertion last:
---------------------
Enter the element:12
12
Insertion last:
---------------------
Enter the element:13
12
13
Insertion last:
---------------------
Enter the element:14
12
13
14
Insertion last:
---------------------
Enter the element:15
12
13
14
15
hope that u understand.Thank you

Implement a doubly linked list in C

I want to insert a node at the beginning of linked list, whenever insertAtBeginning method is called. My code builds well, but i don't get the desired output.
I get the following output:
0------>NULL
The desired output is:
9------>8------>7------>6------>5------>4------>3------>2------>1------>0------>NULL
Following is my code:
#include<stdio.h>
#include<stdlib.h>
struct dll{
int data;
struct dll* previous;
struct dll* next;
};
struct dll* insertAtBeginning(int a, struct dll* head){
if(head == NULL){
head->data = a;
head->previous = NULL;
head->next = NULL;
return head;
}
else{
struct dll *first;
first = (struct dll*) malloc( sizeof(struct dll));
first->data = a;
first->next = head;
head->previous = first;
first->previous = NULL;
head = first;
free(first);
return head;
}
}
void display_from_first(struct dll* head){
struct dll *temp;
temp = head;
printf("\nThe linked list contains: ");
while(temp != NULL) {
printf("%d------>",temp->data);
temp = temp->next;
}
printf("NULL\n");
free(temp);
}
int main(){
int i = 0;
struct dll *head1, *tail1;
head1 = (struct dll*) malloc( sizeof(struct dll));
head1->next = NULL;
head1->previous = NULL;
for(i=0; i<10; i++){
insertAtBeginning(i, head1);
}
display_from_first(head1);
return 0;
}
The code for a doubly linked list is much cleaner if you start with an empty list of two nodes as shown below.
That way you don't have to deal with special cases like if(head==NULL). There's always a node before and after the node that is being inserted (or deleted), so you just hook things up and you're done.
#include <stdio.h>
#include <stdlib.h>
typedef struct s_node Node;
struct s_node
{
Node *prev;
Node *next;
int data;
};
Node *insertAtBeginning( Node *head, int value )
{
// allocate memory for the new node
Node *node = malloc( sizeof(Node) );
if ( node == NULL )
return NULL;
// insert the node at the beginning of the list
Node *temp = head->next;
head->next = node;
temp->prev = node;
// fill in the fields of the node
node->prev = head;
node->next = temp;
node->data = value;
return node;
}
void showList( Node *head )
{
Node *node;
printf( "The list contains: " );
for ( node = head->next; node->next != NULL; node = node->next )
printf( "%d--->", node->data );
printf( "NULL\n" );
}
int main( void )
{
// create an empty list with two nodes
Node head = { NULL , NULL, 0 };
Node tail = { &head, NULL, 0 };
head.next = &tail;
// insert more nodes
for ( int i = 0; i < 10; i++ )
insertAtBeginning( &head, i );
// display the list
showList( &head );
}
There are mainly two problems here :
free(first) : This is not required as you wish to save the memory you just allocated, not delete it.
Your insertAtBeginning() function returns a pointer to head, so in main(), where you are calling this function change it to head1=insertAtBeginning(i, head1); This way your head is also saved.
Here's the code with the two edits :
http://ideone.com/nXwc8z
You have several mistakes here.
1) Your function insertAtBeginning returns pointer to changed list, but you do not update pointer to head of list in the main function.
2) You are freeing just allocated pointer to new node in the insertion function. You think that you are freeing pointer, but actually you say that this place in memory is not needed more and so your node can't be there.
You can't free(first); in insertAtBeginning().
code here.
And btw when you have empty list your display_from_first() prints The linked list contains: 0------>NULL because of
head1 = (struct dll*) malloc( sizeof(struct dll));
head1->next = NULL;
head1->previous = NULL;
in main(). Remove it from main to have correct output

Resources