Want to make linked list function that deletes first Node - c

This is my code. I made three functions for adding a new node, inserting a new node between two others, and one deleting, but I dont know how to delete the first node. I dont even have any idea.
#include <stdlib.h>
#include <stdio.h>
struct Node
{
int data;
struct Node *next;
};
void insert(Node* insertafter, Node* newNode);
void add(Node* llist,Node* newNode);
void deleteafter(Node *llist);
void deletefirts();
int main()
{
struct Node *llist;
struct Node *newNode;
newNode = (Node*)malloc(sizeof(struct Node));
newNode->data = 13;
struct Node *newNode2;
newNode2 = (Node*)malloc(sizeof(struct Node));
newNode2->data = 14;
llist = (Node*)malloc(sizeof(struct Node));
llist->data = 10;
llist->next = (Node*)malloc(sizeof(struct Node));
llist->next->data = 15;
llist->next->next = NULL;
insert(llist,newNode);
add(llist,newNode2);
if(llist->next == NULL)
printf("shecdoma");
struct Node *cursor = llist;
while (cursor != NULL)
{
printf("%d\n", cursor->data);
cursor = cursor->next;
}
system("pause");
return 0;
}
void insert(Node* insertafter, Node *newNode)
{
newNode->next = insertafter->next;
insertafter->next = newNode;
}
void add(Node* llist,Node *newNode)
{
if(llist->next == NULL)
{
llist->next = newNode;
newNode->next = NULL;
}
else
{
while(llist->next != NULL)
{
llist = llist->next;
}
add(llist,newNode);
}
void deleteafter(Node *llist)
{
if(llist->next != NUll)
llist->next = llist->next->next;
}
void deletefirst();
{
}

You can use something like:
void deletefirst (struct Node **head) {
struct Node *tmp = *head; // save old head for freeing.
if (tmp == NULL) return; // list empty? then do nothing.
*head = tmp->next; // advance head to second node.
free (tmp); // free old head.
}
You pass in the pointer to the head so that you can change it. Deleting nodes other than the first does not require this but deleting the first node does.
You set up a temporary pointer to the head so you free it, then you change the head to point to its next element. Then you free the old head and return.

void deleteFirst(Node** list)
{
Node* temp = *list;
if (*list != NULL)
{
*list = (*list)->next;
free(temp);
}
}

Related

Segmentation fault in linked list program (c language)

I'm trying to write a code for linked lists using c++. Insert at begin and Insert at end are not working for some reason. Here is the code.
`
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
void insertAtBeginning(int );
void insertAtEnd(int );
void printLL();
struct Node
{
int data;
struct Node *link;
};
struct Node *head;
int main()
{
struct Node *temp, *newnode;
int ch=1, i=1, info;
head = NULL;
while(ch)
{
printf("Enter data: ");
scanf("%d", &info);
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = info;
newnode->link = NULL;
if(head == NULL)
{
head = newnode;
temp = newnode;
}
else
{
temp ->link = newnode;
temp = newnode;
}
printf("You wish to continue? (press 0 to terminate)\n");
scanf("%d",&ch);
if(!ch)
{
break;
}
}
temp = head;
while(temp!=NULL)
{
printf("%d -> ",temp->data);
temp = temp->link;
}
printf("\n");
insertAtBeginning(50);
insertAtEnd(150);
//printLL();
}
void insertAtBeginning(int info)
{
struct Node *newnode;
newnode->data = info;
printf("\n%d\n", newnode ->data);
newnode->link = head;
head = newnode;
}
void insertAtEnd(int info)
{
struct Node *temp, *newnode;
newnode->link = NULL;
newnode->data = info;
temp = head;
while(temp!=NULL)
{
temp = temp->link;
}
temp->link = newnode;
printf("\n%d\n", newnode -> data);
}
void printLL()
{
struct Node *temp;
temp = head;
while(temp!=NULL)
{
printf("%d -> ",temp->data);
temp = temp->link;
}
}
`
The problem is somewhere around newnode->data = info in the functions.
I created two functions, one to insert an element at beginning and one to insert an element at end. In both of them, i've created a newnode. The problem is I cannot insert data into those nodes.
When you want to append a new node to the end of a linked list, you must find your last node (a node which its link is NULL, not itself). Also, it is better to use meaningful variable name (temp is too general name). You also forgot to malloc new nodes in insertAtBeginning and insertAtEnd functions. I've fixed these issues in the following code
#include<stdio.h>
#include<stdlib.h>
void insertAtBeginning(int );
void insertAtEnd(int );
void printLL();
struct Node
{
int data;
struct Node *link;
};
struct Node *head = NULL;
int main()
{
struct Node *it, *newnode, *tail;
int ch=1, i=1, info;
while(ch){
printf("Enter data: ");
scanf("%d", &info);
newnode = malloc(sizeof(struct Node));
newnode->data = info;
newnode->link = NULL;
if (head == NULL) {
head = newnode;
tail = newnode;
} else {
tail->link = newnode;
tail = newnode;
}
printf("You wish to continue? (press 0 to terminate, else to continue)\n");
scanf("%d",&ch);
if(ch == 0) {
break;
}
}
it = head;
while(it != NULL) {
printf("%d -> ",it->data);
it = it->link;
}
printf("\n");
insertAtBeginning(50);
insertAtEnd(150);
}
void insertAtBeginning(int info)
{
struct Node *newnode;
newnode = malloc(sizeof(struct Node));
newnode->data = info;
printf("\n%d\n", newnode->data);
newnode->link = head;
head = newnode;
}
void insertAtEnd(int info)
{
struct Node *it, *newnode;
newnode = malloc(sizeof(struct Node));
newnode->link = NULL;
newnode->data = info;
it = head;
while(it->link != NULL)
{
it = it->link;
}
it->link = newnode;
printf("\n%d\n", newnode->data);
}
void printLL()
{
struct Node *it;
it = head;
while(it!=NULL)
{
printf("%d -> ",it->data);
it = it->link;
}
}
You're treating your uninitialized stack variable (struct Node *newnode) as a pointer to a struct Node and trying to update its fields:
struct Node *newnode;
newnode->data = info;
This doesn't work because the value of newnode is whatever garbage was on the stack beforehand, and trying to deref it (*newnode) will likely give a seg fault since you're trying to read from some unknown memory address.
Notice how inside main, you assign a result from malloc to newnode, this means you know that (given that malloc didn't return NULL), the pointer is valid, and you're free to use the memory it points to.

Element deletion in single linked list at head not working

#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *second = NULL;
struct node *third = NULL;
void insertAtBeg(struct node *n, int data) {
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
temp->next = head;
head = temp;
}
void insertAtEnd(struct node *n, int data) {
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
temp->data = data;
temp->next = NULL;
while (n->next != NULL) {
n = n->next;
}
n->next = temp;
}
void deleteElement(struct node *head, int data) {
if (head->data == data) {
struct node *temp;
temp = head;
head = head->next;
free(temp);
printf("after deletion at head in function\n");
printList(head);
}
}
void printList(struct node *n) {
while (n != NULL) {
printf("%d\n", n->data);
n = n->next;
}
}
void main() {
head = (struct node*)malloc(sizeof(struct node));
second = (struct node*)malloc(sizeof(struct node));
third = (struct node*)malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
printList(head);
insertAtBeg(head, 0);
printf("after insertion at beginning\n");
printList(head);
insertAtEnd(head, 4);
printf("after insertion at End\n");
printList(head);
deleteElement(head, 0);
printf("after deletion at head in main\n");
printList(head);
}
output of the code is
1
2
3
after insertion at beginning
0
1
2
3
after insertion at End
0
1
2
3
4
after deletion at head in function
1
2
3
4
after deletion at head in main
0
1
2
3
4
Why is there a difference in output of the function called in main and the function called in another function.ie.after deletion at head in function and after deletion at head in main, when both are supposed to be deleting element from the same list
The problem is you need a way to modify the head of the list when inserting and/or deleting elements from the list.
A simple way to do this is for these functions to return a potentially updated value of the head pointer and for the caller to store this return value into it's head variable.
Here is a modified version of your code with these semantics:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insertAtBeg(struct node *head, int data) {
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
// should test for memory allocation failure
temp->data = data;
temp->next = head;
return temp;
}
struct node *insertAtEnd(struct node *head, int data) {
struct node *temp;
struct node *n;
temp = (struct node*)malloc(sizeof(struct node));
// should test for memory allocation failure
temp->data = data;
temp->next = NULL;
if (head == NULL)
return temp;
n = head;
while (n->next != NULL) {
n = n->next;
}
n->next = temp;
return head;
}
struct node *deleteElement(struct node *head, int data) {
// delete the first node with a given data
if (head->data == data) {
struct node *temp = head;
head = head->next;
free(temp);
} else {
struct node *n = head;
while (n->next != NULL) {
if (n->next->data == data) {
struct node *temp = n->next;
n->next = temp->next;
free(temp);
break;
}
}
}
return head;
}
void printList(const struct node *n) {
while (n != NULL) {
printf("%d\n", n->data);
n = n->next;
}
}
int main() {
struct node *head = NULL;
head = insertAtBeg(head, 1);
head = insertAtEnd(head, 2);
head = insertAtEnd(head, 3);
printList(head);
head = insertAtBeg(head, 0);
printf("after insertion at beginning\n");
printList(head);
head = insertAtEnd(head, 4);
printf("after insertion at End\n");
printList(head);
head = deleteElement(head, 0);
printf("after deletion at head in main\n");
printList(head);
// should free the list
return 0;
}
An alternative is to pass the address of the list head pointer so the function can modify it if needed.
Here is a modified version of your code with this alternative approach:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insertAtBeg(struct node **headp, int data) {
struct node *temp = malloc(sizeof(*temp));
if (temp != NULL) {
temp->data = data;
temp->next = *headp;
*headp = temp;
}
return temp;
}
struct node *insertAtEnd(struct node **headp, int data) {
struct node *temp = malloc(sizeof(*temp));
if (temp != NULL) {
temp->data = data;
temp->next = NULL;
if (*headp == NULL) {
*headp = temp;
} else {
struct node *n = *headp;
while (n->next != NULL) {
n = n->next;
}
n->next = temp;
}
}
return temp;
}
int deleteElement(struct node **headp, int data) {
// delete the first node with a given data
struct node *head = *headp;
if (head->data == data) {
*headp = head->next;
free(temp);
return 1; // node was found and freed
} else {
struct node *n = head;
while (n->next != NULL) {
if (n->next->data == data) {
struct node *temp = n->next;
n->next = temp->next;
free(temp);
return 1; // node was found and freed
}
}
return 0; // node not found
}
}
void printList(const struct node *n) {
while (n != NULL) {
printf("%d\n", n->data);
n = n->next;
}
}
int main() {
struct node *head = NULL;
insertAtBeg(&head, 1);
insertAtEnd(&head, 2);
insertAtEnd(&head, 3);
printList(head);
insertAtBeg(&head, 0);
printf("after insertion at beginning\n");
printList(head);
insertAtEnd(&head, 4);
printf("after insertion at End\n");
printList(head);
deleteElement(&head, 0);
printf("after deletion at head in main\n");
printList(head);
// free the list
while (head != NULL) {
deleteElement(&head, head->data);
}
return 0;
}
This alternative approach uses double pointers, so it is a bit more difficult for beginners to comprehend, but it has a strong advantage: the functions can update the list pointer and provide a meaningful return value that can be tested to detect errors. For example insertAtBeg() and insertAtEnd() return NULL if the new node could not be allocated but preserve the list. Similarly deleteElement() can return an indicator showing whether the element was found or not.
With this approach, you can write functions to pop the first or last element of the list, or the one at a given index, or one with a given data, while updating the list pointer as needed.
In the function void deleteElement(struct node *head,int data) you are passing a pointer to the head node. If you make changes to the node, then that works because you are pointing to the actual node. However, the variable head is a local copy of the pointer, which is not the one in main. When you change head to head->next that is only changing the local copy, so it has no effect outside deleteElement.
ADVANCED LEVEL POINTERS
To actually change head you have to pass a pointer to it, making a double pointer:
void deleteElement(struct node **phead,int data) {
struct node *temp;
temp = *phead;
*phead = (*phead)->next;
this means you have to pass the address of head &head as the parameter.

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.

Freeing linked list crashes when on last node

This is a continuation of a problem I posted yesterday, which I thought was solved, but turns out another problem has been encountered with the way I iterate through the loop and its exit condition. I felt a new question thread might be more appropriate.
The following freeAllListMembers() function seems to be working, up until the last iteration of the loop because it is trying to free "temp" but temp has already been freed, what method can I use to exit this loop and keep it from running once more, everything I have tried doesn't seem to be working.
thanks for any insight
int main() {
struct node *head = NULL;
createList(&head);
//do stuff with list
freeAllListMembers(&head);
return 0;
}
int createList(struct node **head) {
struct node *newNode= NULL;
for(int I = 0; I < 100; I++)
{
struct node *node = (struct node*)malloc(sizeof(struct node));
node->data = someData;
node->next = NULL;
//if we havent created an initial start node, create it
if (*head == NULL)
{
*head = node;
}
//otherwise, navigate to the end of the list to add a new node
else
{
newNode = *head;
while (newNode->next != NULL){
newNode = newNode->next;
}
newNode->next = node;
}
}
return 0;
}
void freeAllListMembers(struct node **head){
struct node *temp;
while (*head != NULL) {
temp = *head;
*head = (*head)->next;
free(temp);
}
return;
}
Cleaning up the example given to remove some small human errors, the program compiles OK, and I can step through OK in GDB. It basically ran after it compiled without errors
#include <malloc.h>
#define someData 12345
struct node
{
int data;
struct node* next;
};
int createList(struct node **head )
{
struct node *newNode= NULL;
int i;
for( i = 0; i < 100; i++)
{
struct node *node = (struct node*)malloc(sizeof(struct node));
node->data = someData;
node->next = NULL;
//if we havent created an initial start node, create it
if (*head == NULL)
{
*head = node;
}
//otherwise, navigate to the end of the list to add a new node
else
{
newNode = *head;
while (newNode->next != NULL){
newNode = newNode->next;
}
newNode->next = node;
}
}
return 0;
}
void freeAllListMembers(struct node **head)
{
struct node *temp;
while (*head != NULL) {
temp = *head;
*head = (*head)->next;
free(temp);
}
return;
}
int main()
{
struct node *head = NULL;
createList(&head);
//do stuff with list
freeAllListMembers(&head);
return 0;
}
I can only guess that you lost whatever your bug was in the 'abstraction' process

Implementing Simple Linked List

Hi I wish to implement a simple linked list and all the values to the end of the list. As simple as that but I am not able to do so. Can you please tell me where I am doing it wrong ? Initially I am declaring a pointer and assigning NULL value to it. Later in each iteration I am allocating memory to the pointer that was initially NULL.
#include <stdio.h>
#include <malloc.h>
struct node{
int a;
struct node* next;
};
struct node* insert(struct node* start,int value);
void print(struct node* head);
int main()
{
int a;
struct node* head = NULL;
while(scanf("%d",&a) != EOF)//taking input
{
head = insert(head,a);
print(head);
}
return 0;
}
struct node* insert(struct node* start,int value)
{
struct node* head = start;
while(start != NULL)
{
start = start->next;//getting upto the end of the linked list
}
start = (struct node*)malloc(sizeof(struct node));//allocating memory at the end
start->a = value;
start->next = NULL;
if(head == NULL)
{
return start;//for the base case when list is initally empty
}
return head;
}
void print(struct node* head)
{
while(head != NULL)
{
printf("%d\n",head->a);
head = head->next;
}
return;
}
You're losing your linkage between your tail and your new node, try this instead
struct node* insert(struct node* head,int value)
{
struct node* tail = head;
while(tail != NULL && tail->next != NULL)
{
tail= tail->next;//getting upto the end of the linked list
}
struct node* start = (struct node*)malloc(sizeof(struct node));//allocating memory at the end
start->a = value;
start->next = NULL;
if(head == NULL)
{
return start;//for the base case when list is initally empty
}
else
{
tail->next = start;
}
return head;
}
struct node* insert(struct node* start,int value){
struct node* head = start;
struct node* np = (struct node*)malloc(sizeof(struct node));
np->a = value;
np->next = NULL;
if(head == NULL)
return np;
while(start->next != NULL){
start = start->next;
}
start->next = np;
return head;
}
What makes the approach I am using buggy ?
nodeX
|
+a
|
+next(address to OtherX)
nodeX.next = new_node;//update link(case of OK)
tempPointer = nodeX.next;//address to OtherX set to tempPointer
tempPointer = new_node;//contents of tempPointer changed, but orignal (nodeX.next not change)

Resources