I'm using this append function to append data on my linked-list but it's not showing any output. I've reviewed the code multiple times. This code worked in my previous code.
void append(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
struct Node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next
of it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next!= NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
void printList(struct Node *node)
{
while(node->next!=NULL)
{
printf("%d ",node->data);
node = node->next;
}
}
int main()
{
struct Node *head = NULL;
push(&head,7);
push(&head,1);
push(&head, 3);
push(&head, 2);
append(&head,5);
puts("Created Linked List: ");
printList(head);
//deleteNode(&head, 1);
puts("\nLinked List after Deletion of 1: ");
printList(head);
return 0;
}
It's giving output:
2->3->1->7
Although I need output:
2->3->1->7->5
Should I make the changes in linked list management?
The problem is just on printing out in printList():
while(node->next!=NULL)
The very last node has the value 5 and node->next == NULL, so the loop will terminate without printing. Simply change to:
while(node != NULL)
Related
I am beginner to coding and I started learning C recently.
I wrote this code myself after learning concepts recently. I need few suggestions which can optimize my code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
typedef struct Node{
int data;
struct Node* next;
}
node;
//function to add node at the front
void push(node** head_ref, int new_data){
//allocate node
node* new_node = (node*)malloc(sizeof(node));
//put in new data
new_node->data = new_data;
//make new node as head
new_node->next = (*head_ref);
//move the head to new node
(*head_ref) = new_node;
}
//function to add node after a certain node
void insertAfter(node* prev_node,int new_data){
//check if previous node is null
if(prev_node == NULL){
printf("the given previous node cannot be NULL");
return;
}
//allocate node
node* new_node = (node*)malloc(sizeof(node));
//put in new data
new_node->data = new_data;
//Make next of new node as next of prev_node
new_node->next = prev_node->next;
//move the next of prev_node as new_node
prev_node->next = new_node;
}
//function to add a new node at end
void append(node** head_ref, int new_data){
//allocate data
node* new_node = (node*)malloc(sizeof(node));
node* last = *head_ref;
//put in the new data
new_node->data = new_data;
//new node is going to be last to make its next null
new_node->next = NULL;
//If the Linked List is empty, then make the new node as head
if(*head_ref == NULL){
*head_ref = new_node;
return;
}
//else move to last node
while(last != NULL){
last = last->next;
}
last->next = new_node;
return;
}
void printList(node* nodee)
{
while (nodee != NULL)
{
printf(" %d ", nodee->data);
nodee = nodee->next;
}
}
int main()
{
//Start with the empty list
struct Node* head = NULL;
// Insert 6. So linked list becomes 6->NULL
append(&head, 6);
// Insert 7 at the beginning. So linked list becomes 7->6->NULL
push(&head, 7);
// Insert 1 at the beginning. So linked list becomes 1->7->6->NULL
push(&head, 1);
// Insert 4 at the end. So linked list becomes 1->7->6->4->NULL
append(&head, 4);
// Insert 8, after 7. So linked list becomes 1->7->8->6->4->NULL
insertAfter(head->next, 8);
printf("\n Created Linked list is: ");
printList(head);
return 0;
}
Observe the following code in the append function:
while(last != NULL){
last = last->next;
}
last->next = new_node;
The exit condition for the while loop is that last must be NULL. Therefore the next line last->next is guaranteed to dereference a NULL pointer thus causing a segmentation fault.
I was looking over examples of dynamic memory allocation being used in c programs but I've noticed that many of them do not use free at the end. I was wondering if that's just an error on the programmer's part or if there are some instances in which you shouldn't free up pointers at the end. Here is an example I saw. If I am right and there should be a free where would be the appropriate place to put it? (https://www.geeksforgeeks.org/linked-list-set-2-inserting-a-node/)
// A complete working C program to demonstrate all insertion methods
// on Linked List
#include <stdio.h>
#include <stdlib.h>
// A linked list node
struct Node
{
int data;
struct Node *next;
};
/* Given a reference (pointer to pointer) to the head of a list and
an int, inserts a new node on the front of the list. */
void push(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
/* 2. put in the data */
new_node->data = new_data;
/* 3. Make next of new node as head */
new_node->next = (*head_ref);
/* 4. move the head to point to the new node */
(*head_ref) = new_node;
}
/* Given a node prev_node, insert a new node after the given
prev_node */
void insertAfter(struct Node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
if (prev_node == NULL)
{
printf("the given previous node cannot be NULL");
return;
}
/* 2. allocate new node */
struct Node* new_node =(struct Node*) malloc(sizeof(struct Node));
/* 3. put in the data */
new_node->data = new_data;
/* 4. Make next of new node as next of prev_node */
new_node->next = prev_node->next;
/* 5. move the next of prev_node as new_node */
prev_node->next = new_node;
}
/* Given a reference (pointer to pointer) to the head
of a list and an int, appends a new node at the end */
void append(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
struct Node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next of
it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
// This function prints contents of linked list starting from head
void printList(struct Node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
// Insert 6. So linked list becomes 6->NULL
append(&head, 6);
// Insert 7 at the beginning. So linked list becomes 7->6->NULL
push(&head, 7);
// Insert 1 at the beginning. So linked list becomes 1->7->6->NULL
push(&head, 1);
// Insert 4 at the end. So linked list becomes 1->7->6->4->NULL
append(&head, 4);
// Insert 8, after 7. So linked list becomes 1->7->8->6->4->NULL
insertAfter(head->next, 8);
printf("\n Created Linked list is: ");
printList(head);
return 0;
}
At the end of the program all memory is freed anyway so at one level it makes no difference.
Having said that the sample linked list really should have a deleteList function as this is meant to be an example of 'how to do it right'. And that delete should be called at the end of main. Somebody cutting and pasting this code will leak all over the place.
Its also a good habit to get into, tidy up after yourself. If you ever use valgrind you will want it to give you a clean bill of health
There are no circumstances under which it is ever 'bad' to free up the memory you used at the end of the program.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
void push(struct Node** head_ref, int new_data) {
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
new_node->prev = NULL;
if ((*head_ref) != NULL)(*head_ref)->prev = new_node;
(*head_ref) = new_node;}
void append(struct Node** head_ref, int new_data){
/* 1. allocate node */
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
struct Node* last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so
make next of it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new
node as head */
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
return;}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
/* 7. Make last node as previous of new node */
new_node->prev = last;
return;}
void insertAfter(struct Node* prev_node, int new_data){
/*1. check if the given prev_node is NULL */
if (prev_node == NULL) {
printf("the given previous node cannot be NULL");
return;}
/* 2. allocate new node */
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
/* 3. put in the data */
new_node->data = new_data;
/* 4. Make next of new node as next of prev_node */
new_node->next = prev_node->next;
/* 5. Make the next of prev_node as new_node */
prev_node->next = new_node;
/* 6. Make prev_node as previous of new_node */
new_node->prev = prev_node;
/* 7. Change previous of new_node's next node */
if (new_node->next != NULL)
new_node->next->prev = new_node;}
void printList(struct Node* node){
struct Node* last;
printf("\nTraversal in forward direction \n");
while (node != NULL) {
printf(" %d ", node->data);
last = node;
node = node->next;}
printf("\nTraversal in reverse direction \n");
while (last != NULL) {
printf(" %d ", last->data);
last = last->prev;
}}
void sortedInsert(struct Node** head, int new_data) {
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
struct Node* temp;
if ((*head) == NULL || (new_node->data) > (*head)->prev->data) {
append(head, new_data);
return;
}
if ((new_node->data) < ((*head)->data)) {
push(head, new_data);
return;
}
temp = (*head)->next;
while ((temp->data) < (new_node->data)) {
temp = temp->next;
}
insertAfter(head, new_data);
}
int main() {
struct Node* head = NULL;
sortedInsert(&head, 0);
sortedInsert(&head, 9);
sortedInsert(&head, 4);
sortedInsert(&head, 3);
sortedInsert(&head, 34);
sortedInsert(&head, 15);
printf("\n Created Linked list is: ");
printList(head);
return 0;}
I am trying to write a C program where data must be inserted in a ordered way (smaller to higher)
When I run the code program gives error due to the note:
expected 'struct Node *' but argument is of type 'struct Node **'
how can I fix this problem , I have looked up to the other solutions such as : What does the warning - expected ‘struct node **’ but argument is of type ‘struct node **’ mean?
but those couldnt resolve my issue.
Any help is appreciated
insertAfter(head, new_data);
how can I fix this problem
You forgot to dereference struct Node** head as you correctly did at other places in the function sortedInsert; to get the argument type right, it would be insertAfter(*head, new_data).
But still the insertion logic isn't quite right; here's a corrected version:
void sortedInsert(struct Node** head, int new_data) {
// new node is allocated in append(), push() or insertAfter()
struct Node* temp;
if ((*head) == NULL || new_data < (*head)->data) {
push(head, new_data);
return;
}
temp = *head;
while (temp->next && temp->next->data < new_data) {
temp = temp->next;
}
insertAfter(temp, new_data);
}
When you are using the functions you declared you should pass a reference (address) to the head not the head itself as this what your code requires.
As an example, use append(&head, 3) instead of append(head, 3)
I wanted to make a queue using a linked list, but I couldn't make it!
can I know where's the problem? because it gives me to insert only two values!
typedef struct list
{
int data;
struct list* next;
}list;
void move_forward(list* head,list* node)
{
if(head==NULL) exit(1);
while(head->next!=NULL)
head=head->next;
head->next=node;
}
list* insert(list* head,int value)
{
list* node=(list*)malloc(sizeof(list));
node->data=value;
node->next=NULL ;
if(head==NULL)
head=node;
move_forward(head,node);
return head;
}
Given a reference (pointer to pointer) to the head
of a list and an int, insert a new node at the end
void insertAtEnd(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next
of it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
struct Node *last = *head_ref;
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
I am trying to insert nodes in a linked list. I have tried to insert nodes at front, at the end and after a particular node.
I think that the code is fine and should work. However, this code is giving run time error. Please explain why is it giving a run time error?
Insertion in a linked list
#include <stdio.h>
#include <stdlib.h>
// A linked list node
struct node
{
int data;
struct node *next;
};
void push(struct node* head, int new_data)
{
/* 1. allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* 2. put in the data */
new_node->data = new_data;
/* 3. Make next of new node as head */
new_node->next = head;
/* 4. move the head to point to the new node */
head = new_node;
}
/* Given a node prev_node, insert a new node after the given prev_node */
void insertAfter(struct node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
if (prev_node == NULL)
{
printf("the given previous node cannot be NULL");
return;
}
/* 2. allocate new node */
struct node* new_node =(struct node*) malloc(sizeof(struct node));
/* 3. put in the data */
new_node->data = new_data;
/* 4. Make next of new node as next of prev_node */
new_node->next = prev_node->next;
/* 5. move the next of prev_node as new_node */
prev_node->next = new_node;
}
void append(struct node* head, int new_data)
{
/* 1. allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = head;
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next of it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty, then make the new node as head */
if (head == NULL)
{
head = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
// This function prints contents of linked list starting from the given node
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty list */
struct node* head = NULL;
append(head, 6);
push(head, 7);
push(head, 1);
append(head, 4);
insertAfter(head->next, 8);
printf("\n Created Linked list is: ");
printList(head);
getchar();
return 0;
}
Every place you're loosing your head pointer
You should preserve its address in all functions, use struct node**, and update the pointer
using *head and (*prev_node)
void push(struct node** head, int new_data)
{ //...
// *head
}
void insertAfter(struct node** prev_node, int new_data)
{ //...
// (*prev_node)
}
void append(struct node** head, int new_data)
{ //...
// *head
}
See here
PS:There may be logical mistake
Also, make sure you're releasing memory using free() calls once you're done with everything.