Singly Linked List Creation in C - c

I want to create a singly linked list using C. Why is this piece of code not working? The code is given below. I am using CodeBlocks for running this which is an opensource compiler.
#include<stdio.h>
#include<malloc.h>
struct node
{
int info;
struct node *next;
}*first=NULL;
void create()
{
struct node *ptr;
int i,n;
printf("Enter the number of nodes");
scanf("%d", &n);
for(i=0;i<n;i++)
{
ptr=(struct node *)malloc(sizeof(struct node));
printf("Enter the data.");
scanf("%d",&ptr->info);
ptr=ptr->next;
if(first==NULL)
{first=ptr;}
}
ptr->next=NULL;
}
void main()
{
create();
}

When you do ptr=ptr->next; in your loop, you loose ptr and then you point to garbage because next is not yet initialized. So first link ptr into the list and then go to next.
Doing that I leave for you as excercise.

Related

I got this code to inset an element at the end of the list.Segmentation fault

Hey guys i code this code for inserting an element at the end of the list
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link;
};
struct node*head;
void insert(int x){
struct node*temp=(node*)malloc(sizeof(struct node));
temp->data=x;
temp->link=NULL;
struct node*temp1=head;
while(temp1->link!=NULL)
temp1=temp1->link;
temp1->link=temp;
};
void display(){
struct node*temp=head;
printf("LIst is:");
while(temp!=NULL){
printf("%d",temp->data);
temp=temp->link;
}
printf("\n");
};
int main()
{ head=NULL;
int n,i,x;
printf("Enter the number of elements:");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter the elements:");
scanf("%d",&x);
insert(x);
display();
}
}
Every time i compile it.It shows
Segmentation fault core dumped
please help
i don't know what wrong
am i accessing memory that “does not belong to me.
You assign head to temp1
struct node*temp1=head;
And at this moment head is NULL
then you dereference temp1 (NULL)
while(temp1->link!=NULL)
That's why you get a segfault.
head is NULL to start with. So when you do:
struct node*temp1=head;
while(temp1->link!=NULL)
^^^^^
you dereference NULL and the program crashes.
You need an extra if statement like to handle the case where head is NULL.
...
temp->link=NULL;
if (head == NULL)
{
head = temp;
return;
}
struct node*temp1=head;
...
BTW: In general it's a bad idea to have a global variable head.
To avoid a global variable you can do two things - either return the head pointer on every call to insert or pass the addsress of the head to the function. I prefer the last. It looks like:
void insert(struct node** pHead, int x){
struct node* temp=(node*)malloc(sizeof(struct node));
temp->data=x;
temp->link=NULL;
if (*pHead == NULL)
{
*pHead = temp; // Update head
return;
}
struct node* temp1 = *pHead;
while(temp1->link!=NULL)
temp1=temp1->link;
temp1->link=temp;
};
and call it like:
int main()
{
struct node* head=NULL; // Use a local variable
int n,i,x;
printf("Enter the number of elements:");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter the elements:");
scanf("%d",&x);
insert(&head, x); // Pass the address of head
....
}
}

How can I change my code so that the output will be equal to all the data elements in the nodes?

I learned linked list today and tried this code. I wanted to 5 input values to the list using a for loop. At the bottom of the for loop, "head = head->next"
advances the head pointer to the next node in the list and when the loop terminates,the last node in the list has its .next field set to NULL to mark the end of the list and the while loop is then used to output the list. But as I compiled and run the code the output values of the list are NOT THE SAME ! as the input value. Where am I going wrong here?
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
int key;
struct node* next;
};
struct node* head=NULL;
int main(){
int i;
int a;
int b;
head=(struct node*)malloc(sizeof(struct node));//allocated memory
for(i=0;i<5;i++){
scanf("%d %d",&a,&b);
head->data=a;
head->key=b;
head->next=(struct node*)malloc(sizeof(struct node));
head=head->next;
}
head->next=NULL;
int j;
struct node* m;
m=head;
while(m!=NULL){
printf("%d %d ",m->data,m->key);
m=m->next;
}
}
This is the way of doing insertion at the end of the linked list:
void insertend(int a,int b)
{
current=head;
struct list * temp=(struct list*) malloc(sizeof(list));
temp->data=a;
temp->key=b;
temp->next=NULL;
while(current->next!=NULL)
current=current->next;
current->next=temp;
current=temp;
}
See my comments in below codes and try to understand your mistakes. Also this is not the way you are creating a link list and adding a node into it.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
int key;
struct node* next;
};
struct node* head=NULL;
int main(){
int i;
int a;
int b;
head=(struct node*)malloc(sizeof(struct node));//allocated memory
//above you have create a node and head is pointing to it
for(i=0;i<5;i++){
scanf("%d %d",&a,&b);
head->data=a;
head->key=b;
head->next=(struct node*)malloc(sizeof(struct node));
//till above code it was find
head=head->next;//but here you did the mistake, now head it pointing to the newly created node and you lost the address of first node
//finally when you created the list with 5 nodes head is actually pointing to the last node of the list
//hence it will print only the last node of the list
}
//now do some modification and rewrite the for loop like below
/*
struct node* p=head;
for(i=0;i<5;i++){
scanf("%d %d",&a,&b);
p->data=a;
p->key=b;
p->next=(struct node*)malloc(sizeof(struct node));
p=p->next
} */
// head->next=NULL; //also change this line with below line of code
p->next = NULL;
int j;
struct node* m;
m=head;
while(m!=NULL){
printf("%d %d ",m->data,m->key);
m=m->next;
}
}

Deleting a nth node in a doubly linked list

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node* HEAD;
void Deleteatn(int c)
{
struct node *store,*store1,*temp=HEAD;
if(c==1)
{
store=temp->next;
store->prev=NULL;
HEAD=store;
free(temp);
}
else
{
for(int i=1;i<c-1;i++)
temp=temp->next;
store=temp->next;
store1=store->next;
temp->next=store->next;
//store1->prev=temp;//DOUBT
free(store);
}
}
void print()
{
struct node *temp=HEAD;
while(temp!=NULL)
{
printf("%d ",temp->data);
temp=temp->next;
}
printf("\n");
}
void Insertatend(int b)
{
struct node *n;
n=(struct node *)malloc(sizeof(struct node));
n->data=b;
n->prev=NULL;
n->next=NULL;
if(HEAD==NULL)
HEAD=n;
else
{
struct node *store,*temp=HEAD;
while(temp!=NULL)
{
store=temp;
temp=temp->next;
}
store->next=n;
n->prev=store;
}
}
int main()
{
int a,b,c;
printf("How many Numbers need to be inserted?\n");
scanf("%d",&a);
for(int i=0;i<a;i++)
{
printf("Enter a number\n");
scanf("%d",&b);
Insertatend(b);
}
printf("The List is\n");
print();
printf("Enter which node need to be deleted?\n");
scanf("%d",&c);
Deleteatn(c);
printf("The List After Deletion is\n");
print();
return 0;
}
Here I have written a program to delete a nth node in a doubly linked list ,I have a doubt that without making a Backward link,how does the output come correctly.So in doubly linked list is it not mandatory to make both forward and backward link?
I have mentioned the code line as doubt,without that code,how is it working???
You can find the issue when you traverse back.
Since you are traversing in forward direction its working fine like a singly linked list.

Singly Linked List in C (Warning)

I am trying to implement singly linked list. Is this correct? Getting this warning "non portable pointer conversion". How do i check if the SLL is working? Is it connected to each other? By the way, I am using Turbo C. I am still in this creating and inserting the nodes part.
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
}*start=NULL;
void creat(int *num)
{
struct node *new_node,*current;
new_node=(struct node *)malloc(sizeof(struct node));
new_node->data=num;
new_node->next=NULL;
if(start==NULL)
{
start=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
}
main()
{
int binrange,max=100,n,i,divi;
clrscr();
printf("enter range: ");
scanf("%d",&binrange);
n=max/binrange;
divi=max/n;
for(i=0;i<=max;i++)
{
if(i%divi==0 && i>0)
{
//create nodes here
//store i into nodes
creat(&i);
}
}
getch();
}
new_node->data=num;
should be
new_node->data=*num;
num is a pointer and *num gives the value to be stored in the new_node->data
Assigning pointer to a variable of type int is giving a valid warning.

How to get data from user for linked list

I tried to create linked list in C which will allow the user to insert data, print the list and exit from the program. I can insert the data and print the list one time but when I try to print the list again it shows list as empty. The address of the header has been changed to NULL.
#include <stdio.h>
#include <stdlib.h>
struct Node* head;
struct Node
{
int data;
struct Node* next;
};
void Insert(int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=head;
head=temp;
}
print()
{
printf("%d",head);
printf("\nthe list is\n");
while(head!=NULL)
{
printf("%d\t",head->data);
head=head->next;
}
}
int main()
{
//head=NULL;
int n,i,x,option;
do
{
printf("\n1.Insert 2.Print 3.Exit");
printf("\nenter option:");
scanf("%d",&option);
if(option==1){
printf("\nTotal no to be entered:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter the number:");
scanf("%d",&x);
Insert(x);
}}
else{
if(option==2){
print();
}
}
}while(option!=3);
}
Your print method changes the head pointer, so next time you access the list, head will point to null. You should use a different pointer for the iteration:
void print()
{
Node* iter = head;
printf("%d", iter);
printf("\nthe list is\n");
while(iter!=NULL)
{
printf("%d\t",iter->data);
iter=iter->next;
}
}
You are lopping over the linked list with the pointer head to the head of your list, so at the end of the loop, head reaches the end of the list and nothing remains to print.
To resolve the problem you need to keep head on its place (the head of the list) and loop with a second pointer loop_ptr
print()
{ Node* loop_ptr = head;// create a pointer to loop with
printf("%d",loop_ptr);
printf("\nthe list is\n");
while(loop_ptr!=NULL)
{
printf("%d\t",loop_ptr->data);
loop_ptr=loop_ptr->next;// at the end head points always to the head of your list
}
}
Nota Bene:
struct Node* next;
struct Node* head;
This is a bad practice when dealing with pointers. Unlike other data structures, a pointer must always properly initialized to avoid unexpected mess. In your case, you can do this:
struct Node* next= NULL;
struct Node* head= NULL;

Resources