Why the following implementation overrides the elements/ or prints only one element - c

I am trying to implement linked list in c. In the insertion of the element, if the head is not NULL, I am trying to add a node in the beginning of the linked list
Here is my code
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
struct Node* head ;
void insert(int data){
struct Node* temp = (struct Node*) malloc(sizeof(struct Node));
temp->data = data;
if(head!=NULL){
temp = head;
head = temp;
}
temp -> next = NULL;
head = temp;
}
void print(){
struct Node* temp = head;
while(temp!=NULL){
printf("%d \n",temp->data);
temp = temp->next;
}
}
int main(){
head = NULL;
insert(2);
insert(3);
insert(5);
print();
return 0;
}
But on print function, I am getting only 2 as output. What might be the reason?

The function should be defined the following way
void insert( int data )
{
struct Node *temp = ( struct Node * )malloc( sizeof( struct Node ) );
if ( temp != NULL )
{
temp->data = data;
temp->next = head;
head = temp;
}
}
Or the following way
_Bool insert( int data )
{
_Bool success;
struct Node *temp = ( struct Node * )malloc( sizeof( struct Node ) );
if ( ( success = temp != NULL ) )
{
temp->data = data;
temp->next = head;
head = temp;
}
return success;
}
As for your code then you always assign head itself when it is not the first node
if(head!=NULL){
temp = head;
head = temp;
}
And as result the program has memory leaks and the list contains always the first inserted element.
Of course you need to write also a function that will free all allocated memory when the list is not needed any more.

this may be the insert function
void insert(int n)
{
if(head==NULL)
{
head=(struct Node*)malloc(sizeof(struct Node));
head->data=n;
head->next=NULL;
}
else
{
struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=n;
temp->next=head;
head=temp;
}
}

Related

What is the logical error in my attempt to implement the insertion of nodes in the linked list?

I'm unable to get an output for inserting nodes at the beginning, end, and after a given node. I'm not very sure if there is anything that I missed out in the main(). I'm unable to point out my logical error in the program
`
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
//Inserts at the begining
void push(struct node **head, int x){
struct node *newnode = (struct node *)malloc(sizeof(struct node));
newnode->data = x;
*head = newnode;
newnode->next = (*head);
*head = newnode;
}
//Insert at the last
void append(struct node **head, int x){
struct node *temp;
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = x;
newnode->next = 0;
if(*head == 0){
*head = newnode;
}
temp = *head;
while(temp->next != 0){
temp = temp->next;
}
temp->next = newnode;
}
//inserting at a given node
void insertAfter(struct node* temp, int x){
if(temp == NULL){
printf("previous node cannot be NULL");
}
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = x;
newnode->next = temp->next;
temp->next = newnode;
}
void printList(struct node *temp){
while(temp->next != NULL){
printf("%d",temp->data);
}
temp = temp->next;
}
int main(){
struct node *head = NULL;
append(&head,6);
push(&head, 7);
push(&head, 1);
append(&head, 4);
insertAfter(head->next, 8);
printf("Created linked list is:\n");
printList(head);
return 0;
}
`
The output is 1 7 8 6 4
But I'm getting no output and no errors as well
Within the function print_list there can be an infinite loop because this statement
temp = temp->next;
is placed after the while loop
void printList(struct node *temp){
while(temp->next != NULL){
printf("%d",temp->data);
}
temp = temp->next;
}
The function can look for example the following way
void printList( const struct node *head )
{
for ( ; head != NULL; head = head->next )
printf( "%d -> ", head->data );
}
puts( "null" );
}
Pay attention to that within the function push this statement
*head = newnode;
is present twice.
Also the functions are unsafe because there is no check whether memory was allocated successfully within the functions.
For example the function append could be declared and defined the following way
//Insert at the last
int append( struct node **head, int x )
{
struct node *newnode = malloc( sizeof( *newnode ) );
int success = newnode != NULL;
if ( success )
{
newnode->data = x;
newnode->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = newnode;
}
return success;
}

Duplicating a linked list without using recursion

I'm trying to figure out how to duplicate a linked list, and after debugging on Vs code I'm getting a segmentation fault on cuurent->data = temp->data;
and I'm not sure why this is happening.
and this is the code:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
struct node* head;
struct node* head2;
struct node* Insert(struct node* head, int x)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = head;
return temp;
}
void Print(struct node* head)
{
struct node* tmp1 = head;
printf("List is:");
while (tmp1 != NULL) {
printf(" %d", tmp1->data);
tmp1 = tmp1->next;
}
printf("\n");
}
struct node* dupe(struct node* head, struct node* head2)
{
if (head == NULL)
return NULL;
struct node* temp = head;
struct node* prev = NULL;
struct node* cuurent = (struct node*)malloc(sizeof(struct node));
cuurent->data = temp->data;
if (head2 == NULL) {
cuurent->next = head2;
head2 = cuurent;
}
while (temp != NULL) {
temp = temp->next;
cuurent = (struct node*)malloc(sizeof(struct node));
cuurent->data = temp->data;
cuurent->next = prev;
prev = cuurent;
}
return head2;
}
int main(void)
{
head = NULL;
head2 = NULL;
head = Insert(head, 4);
head = Insert(head, 2);
head = Insert(head, 3);
head = Insert(head, 5);
head2 = dupe(head, head2);
Print(head);
Print(head2);
}
As pointed out in the comments,
while (temp != NULL) {
temp = temp->next;
changes the value of temp immediately after guarding against a null pointer value.
This eventually means
cuurent->data = temp->data;
will cause Undefined Behaviour by dereferencing temp when it is the null pointer value.
You can apply the exact same looping principles shown in Print to copy the list. The only difference being you must save a pointer to the first node.
The same principle can be used again when it comes time to free the memory.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insert(struct node *next, int x)
{
struct node *n = malloc(sizeof *n);
n->data = x;
n->next = next;
return n;
}
void print_list(struct node *head)
{
printf("List is: ");
while (head) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
void free_list(struct node *head)
{
struct node *t;
while (head) {
t = head->next;
free(head);
head = t;
}
}
struct node *copy_list(struct node *head)
{
struct node *root = NULL;
for (struct node *current; head; head = head->next) {
struct node *new = insert(NULL, head->data);
if (!root)
root = new;
else
current->next = new;
current = new;
}
return root;
}
int main(void)
{
struct node *head = NULL;
head = insert(head, 4);
head = insert(head, 2);
head = insert(head, 3);
head = insert(head, 5);
struct node *head2 = copy_list(head);
print_list(head);
print_list(head2);
free_list(head);
free_list(head2);
}
Output:
List is: 5 3 2 4
List is: 5 3 2 4

Linked list implementation in C(printing only last two nodes)

#include <stdlib.h>
#include <stdio.h>
struct node {
int data;
struct node *next;
};
void addLast(struct node **head, int value);
void printAll(struct node *head);
struct node *head1 = NULL;
int main() {
addLast(&head1, 10);
addLast(&head1, 20);
addLast(&head1, 30);
addLast(&head1, 40);
printAll(head1);
return 0;
}
void addLast(struct node **head, int value) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = value;
if (*head == NULL) {
*head = newNode;
(*head)->next = NULL;
} else {
struct node **temp = head;
while ((*temp)->next != NULL) {
*temp = (*temp)->next;
}
(*temp)->next = newNode;
newNode->next = NULL;
}
}
void printAll(struct node *head) {
struct node *temp = head;
while (temp != NULL) {
printf("%d->", temp->data);
temp = temp->next;
}
printf("\n");
}
addLast() will append the new node at the end of the list, with printAll(), I am printing entire list.
Every time when I am printing the list, I can only see the last two nodes.
Can anyone please help, why loop is not iterating over entire list ?
The function addLast is too complicated and as result is wrong due to this statement
*temp = (*temp)->next;
in the while loop. It always changes the head node.
Define the function the following way
int addLast( struct node **head, int value )
{
struct node *newNode = malloc( sizeof( struct node ) );
int success = newNode != NULL;
if ( success )
{
newNode->data = value;
newNode->next = NULL:
while( *head ) head = &( *head )->next;
*head = newNode;
}
return success;
}
Take into account that there is no need to declare the variable head1 as global. It is better to declare it inside the function main.
Also all the allocated memory should be freed before exiting the program.

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

Insert an element in end of a singly Linked List

I have been trying to fix this code since morning but could get it done. So, finally i need some help in figuring out the error. The code compiles with no error but when i run it from terminal i get an error saying "segmetation error: 11"
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node *next;
};
struct Node *head;
void Insert(int data);
void Print();
int main()
{
head = NULL; //list is empty
Insert(3);
Insert(5);
Insert(2);
Insert(8);
Print();
return 0;
}
void Insert(int data)
{
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
struct Node *temp1 = head;
while(temp1 != NULL)
{
temp1= temp1->next;
}
temp1->next = temp;
}
void Print()
{
struct Node *temp =head;
while(temp != NULL)
{
temp = temp->next;
printf("%d", temp->data);
}
}
You never set head to anything other than NULL.
(Even if you fix the above) temp1 is guaranteed to be NULL by the time you get to temp1->next = temp;.
P.S. I don't think it's such a great practice to call you variables temp, temp1 etc. From those names it is impossible to tell what their supposed function is.
Usually single linked lists have an inserting operation that inserts data at the beginning of the list. Nevertheless your function insert can look the following way
void Insert( int data )
{
struct Node *temp = malloc(sizeof( struct Node ) );
temp->data = data;
temp->next = NULL;
if ( head == NULL )
{
head = temp;
}
else
{
struct Node *current = head;
while ( current->next != NULL ) current = current->next;
current->next = temp;
}
}
It would be better if you check in the function whether the node was allocated.
Function Print also is wrong. It can look like
void Print( void )
{
for ( struct Node *current = head; current != NULL; current = current->next )
{
printf( "%d ", current->data );
}
}
You are writing
while(temp1 != NULL)
Make it like this
while(temp1->next != NULL)
Here, temp1 points to null at the end of loop, and you are trying to add node after null i.e.
null->next =temp;
which must be throwing error.
struct Node *curr;
void Insert(int data){
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next =NULL;
if(head == NULL)
curr = head = temp;
else
curr = curr->next = temp;
}
void Print(){
struct Node *temp =head;
while(temp != NULL){
printf("%d ", temp->data);
temp=temp->next;
}
}

Resources