Unable to create and display linked list in C - c

I want to create integer linked list and display. Suppose there are 3 nodes with values 11,22,33 . But when I display it, its printing only 1st value i.e. 11 . What is going wrong?
NOTE : To create and display linked list , Whether head and p node variable are enough or is it must to take 3 node pointer variables . i.e. head , p and q also?
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}node;
int main()
{
int i, j, num, value;
node *p = NULL;
node *head = NULL;
printf("how many nodes\r\n");
scanf("%d",&num);
for(i = 0 ;i < num ; i++)
{
printf("enter node %d = ",i+1);
scanf("%d",&value);
p = (node *)malloc(sizeof(node));
p->data = value;
p->next = NULL;
if(head == NULL)
{
head = p;
}
}
printf("linked list formed is \r\n");
for(p = head ; p != NULL ; p = p->next)
{
printf("p->data = %d\r\n ",p->data);
}
return 0;
}

You build a forward-chained linked list in input order by constantly updating a target point on which to hang the next node.
Initially that pointer is the head pointer.
The next node will be hung on the next pointer of that previous node.
When done, the last next pointer is set to NULL and you're finished.
It may sound complicated, but utilizing a pointer-to-pointer makes the algorithm surprisingly simple, efficient, and requires no special tedious case for testing for a null head pointer that will only ever be true once. Including added error checking
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} node;
int main()
{
node *head = NULL;
node **pp = &head;
int num;
printf("how many nodes\r\n");
if (scanf("%d", &num) == 1 && num > 0)
{
for (int i=0; i<num;)
{
int value;
printf("enter node %d = ", i+1);
if (scanf("%d", &value) == 1)
{
*pp = malloc(sizeof **pp);
if (*pp == NULL)
{
perror("Failed to allocate new list node");
exit(EXIT_FAILURE);
}
// hang the new node
(*pp)->data = value;
// setup pp to hold address of next pointer
// to populate on the next iteration.
pp = &(*pp)->next;
// next node
++i;
}
else
{
int c;
while ((c = fgetc(stdin)) != EOF && c != '\n');
}
}
// terminate the list
*pp = NULL;
}
printf("linked list formed is:\n");
for (const node *p = head; p != NULL; p = p->next)
{
printf(" p->data = %d\n", p->data);
}
// free the list
while (head)
{
node *p = head;
head = head->next;
free(p);
}
return 0;
}
Sample Run
how many nodes
5
enter node 1 = 1
enter node 2 = 3
enter node 3 = 5
enter node 4 = 7
enter node 5 = 9
linked list formed is:
p->data = 1
p->data = 3
p->data = 5
p->data = 7
p->data = 9

You are just updating the head first time and not creating any links
please find the fixed code below
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}node;
int main()
{
int i, j, num, value;
node *p = NULL;
node *head = NULL;
printf("how many nodes\r\n");
scanf("%d",&num);
for(i = 0 ;i < num ; i++)
{
printf("enter node %d = ",i+1);
scanf("%d",&value);
p = (node *)malloc(sizeof(node));
p->data = value;
p->next = NULL;
// Form links
p->next = head;
head = p;
}
printf("linked list formed is \n");
for(p = head ; p != NULL ; p = p->next)
{
printf("%d ",p->data);
}
printf("\n");
// Freeing memory to avoid mem leaks
for(p = head ; head != NULL ; head = head->next)
{
p = head;
free(p);
}
return 0;
}
You can refer to my library for a more generic implementation of link_list

A change in code by Mohammed Meraj to create the list in the correct order.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
int main()
{
int i, num, value;
node *p = NULL;
node *head = NULL;
node *q = NULL;
printf("how many nodes\r\n");
scanf("%d",&num);
for(i = 0 ;i < num ; i++)
{
printf("enter node %d = ",i+1);
scanf("%d",&value);
p = (node *)malloc(sizeof(node));
p->data = value;
p->next = NULL;
// Form links
if(!q) head = q = p;
else{ q->next = p; q = p; }
}
printf("linked list formed is \n");
for(p = head ; p != NULL ; p = p->next)
{
printf("%d ",p->data);
}
printf("\n");
// Freeing memory to avoid mem leaks
while(head != NULL)
{
p = head;
head = head->next;
free(p);
}
return 0;
}
if you want to do the code with only head and p, it can be done too
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
int main()
{
int i, num, value;
node *p = NULL;
node *head = NULL;
printf("how many nodes\r\n");
scanf("%d",&num);
for(i = 0 ;i < num ; i++)
{
printf("enter node %d = ",i+1);
scanf("%d",&value);
if(!head){
head = (node *)malloc(sizeof(node));
head->data = value;
head->next = NULL;
p = head;
}else{
p->next = (node *)malloc(sizeof(node));
p->next->data = value;
p->next->next = NULL;
p = p->next;
}
}
printf("linked list formed is \n");
for(p = head ; p != NULL ; p = p->next)
{
printf("%d ",p->data);
}
printf("\n");
// Freeing memory to avoid mem leaks
while(head != NULL)
{
p = head;
head = head->next;
free(p);
}
return 0;
}

Related

new to lists, function doesn't print list elements

I am a beginner to C and am learning linked lists. I tried making functions to have everything organised but no matter what i do the function print_list doesn't print the values. The output is only START and END. I noticed that if I put the same block of code directly into the function that builds the lists, then it prints correctly. What am I doing wrong? (Also first time asking on stack overflow)
Thank you to whoever answers.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd
{
int val;
struct nd *next;
} node;
typedef node * Lista;
void print_list(node*currnode)
{
printf("START -> ");
while (currnode != NULL)
{
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node*riempilista(Lista lis){
node *currentNode, *temp;
int i,n;
printf("how many nodes?\n");
scanf("%d",&n);
for (i = 0; i < n; i++)
{
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", &currentNode->val);
if (i == 0)
{
temp = currentNode;
}
else
{
temp->next = currentNode;
temp = currentNode;
}
}
temp->next = NULL;
return lis;
}
int main(){
Lista listautente=NULL;
listautente=riempilista(listautente);
print_list(listautente);
return 0;
}
When you build the list you need to return the head of the list as a result. So you need to store the pointer to the first node. Then when adding a new node you need to know the previous node, so you need to store it as well. The last added node should have next field poiting to NULL otherwise you won't be able to determine the end of the list and will get an exception.
Here is your code slightly edited.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd {
int val;
struct nd *next;
} node;
typedef node *Lista;
void print_list(node *currnode) {
printf("START -> ");
while (currnode != NULL) {
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node *riempilista() {
node *firstNode = NULL, *currentNode = NULL, *previousNode = NULL;
int i, n;
printf("how many nodes?\n");
scanf("%d", &n);
for (i = 0; i < n; ++i) {
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", &currentNode->val);
currentNode->next = NULL;
if (i == 0) {
firstNode = currentNode;
}
if (previousNode != NULL) {
previousNode->next = currentNode;
}
previousNode = currentNode;
}
return firstNode;
}
int main() {
Lista listautente = riempilista();
print_list(listautente);
return 0;
}
I tried to fix your program with minimal changes. Here it is:
Change
node *currentNode, *temp;
to
node *currentNode, *temp, *head;
Change
temp = currentNode;
to
temp = currentNode; head = temp;
Change
return lis;
to
return head;
Here is the link to the modified code:
https://onlinegdb.com/8cjqifgl2

Why does the node not inserted at the end?

After I compile the code, there is no output at all.
Why is the value 10 not inserted at the end of the linked list?
I thought that after p == NULL, the while loop is exited, j->next would be NULL as well. So, the temp node will be inserted at the end of the linked list.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
}*first=NULL;
void Create(int array[], int size)
{
int i;
struct Node *temp, *last;
first = (struct Node*)malloc(sizeof(struct Node));
first->data = array[0];
first->next = NULL;
last = first;
for (i = 1 ; i < size ; i++){
temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = array[i];
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void Print(struct Node *p)
{
while(p != NULL){
printf("%d ", p->data);
p = p->next;
}
}
void InsertingInSortedList(struct Node *p, int value)
{
struct Node *temp , *j = NULL;
temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = value ;
temp->next = NULL;
if(p == NULL){
first = temp;
}
else
{
while(p->data < value && p){
j = p;
p = p->next;
}
temp->next = j->next;
j->next = temp;
}
}
int main (void)
{
int b[] = {1,3,5,7,8,9};
int num = 6;
Create(b,num);
InsertingInSortedList(first, 10);
Print(first);
return 0;
}
The condition p->data < value && p is wrong. You need to check if p is NULL before you dereference p.
The correct condition is p && p->data < value.
Google c short circuit evaluation for more information.

make a list of m nodes, where m is taken in input

Hi this is the code I wrote for create as many nodes as he needs (the m variable), but I noticed that using this method I'm creating one more node. What's the best way of fcreating as many nodes as the user say us?
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int val;
int rip;
struct Node *next;
} node;
node *modify(node *head);
void print(node *head2);
int main(){
int m, i;
printf("How many nodes: \n");
scanf("%d", &m);
node *head = NULL;
head = (node *)malloc(sizeof(node));
node *temp = head;
node *head2 = NULL;
printf("Write the value in HEAD position : \n");
scanf("%d", &temp->val);
temp->rip=0;
temp->next = NULL;
for(i=0; i < m-1; i++)
{
temp->next = (node *)malloc(sizeof(node));
printf("Write the value in position %d: \n", i);
temp = temp->next;
scanf("%d", &temp->val);
temp->rip=0;
temp->next = NULL;
}
head2 = modify(head);
print(head2);
return 0;
}
node *modify(node *head){
int counter, pass, m;
node *curr = head;
node *track = head;
node *precNode;
while (track != NULL){
counter = 0;
pass = 0;
m = track->val;
while( curr != NULL){
if(m == (curr)->val){
pass++;
counter++;
if(pass > 1){
node *removed = curr;
precNode->next = (curr)->next;
curr = (curr)->next;
free(removed);
}
if(pass == 1)
{
precNode = curr;
curr = curr->next;
}
}
else{
precNode = curr;
curr = (curr)->next;
}
}
track->rip = counter;
track = track->next;
curr = track;
}
return head;
}
void print(node *head2){
while(head2 != NULL){
printf("[%d, %d] -> ", head2->val, head2->rip);
head2 = head2->next;
}
printf("\n");
}
```

C Linked List Add Item at the End

I'm writing a program that adds a node at the end of an existing linked list.
The problem is that it doesn't seem to assign to the variable nr of struct node of the last element of the linked list the hard coded value 7.
Here is the code:
#include<stdio.h>
#include<stdlib.h>
struct node {
int nr;
struct node *next;
};
void addNodes(struct node **head, int n);
void displayList(struct node *head);
void addItemLast(struct node *head);
int main() {
struct node* head = NULL;
int n;
printf("Introduceti numarul de noduri: ");
scanf("%d", &n);
addNodes(&head, n);
displayList(head);
addItemLast(head);
displayList(head);
return 0;
}
void addNodes(struct node **head, int n) {
*head = (struct node*)malloc(sizeof(struct node));
struct node *current = *head;
printf("\nIntroduceti %d noduri:\n", n);
for(int i = 0; i < n; i++) {
printf("Element %d = ", i+1);
scanf("%d", &(current -> nr));
current->next = (struct node*)malloc(sizeof(struct node));
current = current->next;
}
current->next = NULL;
}
void displayList(struct node *head) {
struct node *current = head;
int i = 1;
printf("\nElementele introduse sunt:\n");
while(current->next != NULL) {
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}
}
void addItemLast(struct node *head) {
struct node *temp = head, *last;
last = (struct node*)malloc(sizeof(struct node));
if(last == NULL) {
printf("\nMemory cannot be allocated!\n");
} else {
last->nr = 7;
last->next = NULL;
while(1) {
if(temp->next == NULL) {
temp->next = last;
break;
}
temp = temp->next;
}
}
}
The last function, addItemLast(), doesn't work as expected.
This is the output:
Introduceti numarul de noduri: 3
Introduceti 3 noduri:
Element 1 = 1
Element 2 = 2
Element 3 = 3
Elementele introduse sunt:
Elementul 1 = 1
Elementul 2 = 2
Elementul 3 = 3
After the function with the problem runs, I get this output:
Elementele introduse sunt:
Elementul 1 = 1
Elementul 2 = 2
Elementul 3 = 3
Elementul 4 = 13383248
Element 4 does not contain the hard coded value 7, but instead has a garbage value and I can't figure out why.
Your implemenation of addNodes is incorrect, suppose I enter n = 2 , 3 nodes are created but only twice scanf function is called, so as result you have garbage value in some node (nr is not set).
Reimplement it (it works if addItemLast function is properly implemented) :
void addNodes(struct node **head, int n){
printf("\nIntroduceti %d noduri:\n", n);
for(int i = 0; i < n; i++){
struct node* last = addItemLast(*head);
if (*head == NULL)
*head = last;
printf("Element %d = ", i);
scanf("%d", &(last -> nr));
}
}
You need to change addItemLast to handle case when you want to call this function but head is NULL (without testing this case your program crashes while calling addItemLast for empty List):
struct node* addItemLast(struct node *head){
struct node *temp = head, *last;
last = (struct node*)malloc(sizeof(struct node));
if (head == NULL) // <---------
{
last->nr = 7;
last->next = NULL;
return last;
}
if(last == NULL){
printf("\nMemory cannot be allocated!\n");
}else{
last->nr = 7;
last->next = NULL;
while(1){
if(temp->next == NULL){
temp->next = last;
break;
}
temp = temp->next;
}
}
return last;
}
and finally function to display list should be:
void displayList(struct node *head){
struct node *current = head;
int i = 1;
printf("\nElementele introduse sunt:\n");
while(current != NULL){ // <---------
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}
}
You do not have to check if current->next != NULL when accessing the element of current.
Change your while loop to:
while(current != NULL){
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}

Adding two integers represented by linked lists

The question I came across.
Here is what I have done so far
#include <stdio.h>
#include <stdlib.h>
struct node
{
int digit;
struct node *next;
};
struct node *make_node(int num, struct node *head);
struct node *newNode(int digit);
struct node *sum(struct node *num1, struct node *num2);
void print(struct node *node);
int main()
{
int a, b;
struct node *new_nodeA1 = NULL, *new_nodeA2 = NULL;
struct node *new_nodeB1 = NULL, *new_nodeB2 = NULL;
struct node *res = NULL;
printf("\nEnter no. of digits for your two numbers (separate with space) ");
scanf("%d %d", &a, &b);
int n1[a], n2[b];
printf("\n\nEnter first non-negative integer to add: ");
for (int j = 0; j < a; j++)
scanf("%1d", &n1[j]);
printf("Enter second non-negative integer to add: ");
for (int k = 0; k < b; k++)
scanf("%1d", &n2[k]);
/* for (int i = 0; i <= a - 1; i++)
printf("%d\n", n1[i]);
printf("%d\n", a); */
for (int z = 0; z < a - 1; z++)
{
new_nodeA2 = make_node(n1[z], new_nodeA1);
/*new_nodeA2 = newNode(n1[z]);*/
if (new_nodeA1 == NULL)
new_nodeA1 = new_nodeA2;
}
for (int y = 0; y < b - 1; y++)
{
new_nodeB2 = make_node(n2[y], new_nodeB1);
if (new_nodeB1 == NULL)
new_nodeB1 = new_nodeB2;
}
printf("\n");
print(new_nodeA1);
printf("\n");
print(new_nodeB1);
printf("\n")
res = sum(new_nodeA2, new_nodeB2);
printf("Result: ");
print(res);
return 0;
}
struct node *make_node(int num, struct node *head)
{
struct node *temp = malloc(sizeof(struct node));
if (temp == NULL)
{
fprintf(stderr, "Call of malloc() failed\n");
exit(1);
}
if (head != NULL)
head->next = temp;
temp->digit = num;
temp->next = NULL;
return temp;
}
struct node *newNode(int digit)
{
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->digit = digit;
new_node->next = NULL;
return new_node;
}
struct node *sum(struct node *num1, struct node *num2)
{
struct node *res = NULL;
struct node *temp, *prev = NULL;
int carry = 0, sum;
while (num1 != NULL || num2 != NULL)
{
sum = carry + (num1? num1->digit: 0) + (num2? num2->digit: 0);
carry = (sum >= 10)? 1 : 0;
sum = sum % 10;
temp = newNode(sum);
if(res == NULL)
res = temp;
else
prev->next = temp;
prev = temp;
if (num1)
num1 = num1->next;
if (num2)
num2 = num2->next;
}
if (carry > 0)
temp->next = newNode(carry);
return res;
}
void print(struct node *node)
{
while(node != NULL)
{
printf("%d->", node->digit);
node = node->next;
}
printf("\n");
}
My Output
My compiler does not give me any error. I tried debugging my make_node function but I cant catch the problem as to why my nodes are skipping certain digits.
Your linked list insert code is very broken. For this style of list, you need to walk down the list from head->next until a null is found and insert there. Instead, you are always replacing the head->next with your new temp node, thus breaking the list.
You can also add to the list backwards, making the newly added item the head each time and thus get around the traversal for add, but beware this will place your numbers in reverse order (which actually helps when you do your adding, so perhaps this is good too.)

Resources