Linked List elements not getting displayed - c

This is my program in C which always inserts into a linked list at the end. But when I try to print the list elements, nothing is displayed. Here is the code :
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void insert(struct Node *, int);
int main(void)
{
struct Node *head = NULL, *current;
int n, i, x, data;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(head, data);
}
current = head;
while(current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
}
void insert(struct Node *head, int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
I cannot understand what might be the issue. Please help.

Your insert cannot modify head. Change it to
void insert(struct Node **head, int data)
and change it by
*head = newnode;
and call it like this
insert(&head, data);

Here, while you are passing the head pointer to your insert() function, it is not being updated in your main() function.
So, either declare your head pointer as global or return your head pointer and update it in your main() function.
In the below code I had taken the head pointer as global and removed the head pointer as your parameter from the insert() function.
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *head=NULL;
void insert(int);
int main(void)
{
struct Node *current;
int n, i, x, data;
clrscr();
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(data);
}
current = head;
while(current != NULL)
{
printf("%d \n", current->data);
current = current->next;
}
getch();
return 0;
}
void insert(int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}

You need to pass the reference of the head pointer, then only the changes made to it will be visible.
You must declare your function like
void insert(struct Node **, int);
and also call it like
insert(&head, data);
also, make changes to function definition
void insert(struct Node **head, int data)
{
struct Node *newnode, *current = *head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(*head == NULL)
{
*head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}

You need to pass the head by reference as you are making changes to it that should be visible.
insert(head, data);
should become
insert(&head, data);
Also the function signature will change.
void insert(struct Node *head, int data)
should become
void insert(struct Node **head, int data)
Also make appropriate changes in the function.
Like,
current = *head;

Because you are passing the pointer by value. The function operates on a copy of the pointer, and never modifies the original.
Either pass a pointer to the pointer (i.e. a struct head **), or instead have the function return the pointer.
You can try running the following code which will give the output as null
printf("%s",head);
while(current != NULL)
{
printf("%d", current->data);
current = current->next;
}

Related

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.

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;
}
}

What's with the program why is it not printing any result?

struct node{
int data; struct node *next;
};
void push(struct node* head, struct node* n){
if(n!= NULL){
if(head==NULL)
head = n;
else {
n->next = head;
head = n;
}
} else printf("Cannot insert a NULL node");
}
struct node* pop(struct node* head){
if(head!=NULL){
struct node *n = head;
head = head->next;
return n;
} else {
printf("The stack is empty");
return NULL;
}
}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;
}
You need to pass the address of the pointer head to the function push. I your case the head is not getting modified because you are only passing the value in the head.
void push(struct node** head, struct node* n){
if(n!= NULL){
if(*head==NULL)
*head = n;
else {
n->next = *head;
*head = n;
}
} else printf("Cannot insert a NULL node");}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(&head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;}
You are passing the head pointer by value to the function push(head,temp);. The changes to head done inside push will not be reflected in the main() function.
You should pass address of head to push().
push(&head, temp);
and inside push():
*head = n;
Similar change will be required for pop(). You can verify what I am saying by adding a printf inside the loop in main() as: printf("%p\n", head);. The value of head will remain unchanged.
BTW, it is good practice to add a \n at the end of statement inside printf, it flushes the stdout stream immmediately hence your output is printed immediately on stdout (your computer screen).

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)

Pointers Linked Lists C Programming

I don't get why this isn't working... For example I have this.
struct node {
int data;
struct node* next;
};
static int length(struct node* head) {
Does Stuff
};
void main() (
int i;
struct node* head;
i = length(head);
);
but the code doesn't want to work... I get the wrong output. I'm trying to send the pointer to my functions so that they can have access to the data that I malloc. I will post the full code bellow:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node* head);
static void push(struct node* head, int data);
static int pop(struct node* head);
static void appendNode(struct node* head, int data);
static struct node *copyList(struct node* head);
static void printList(struct node* head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node* head) {
int count = 0;
struct node* current = NULL;
current = head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node* head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = head;
head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node* head) {
int val = 0;
struct node* temp = NULL;
if (head != NULL) {
val = head->data;
temp = head->next;
free(head);
head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node* head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node* head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = head;
while (current != NULL) {
appendNode(copy, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node* head) {
struct node* current = NULL;
printf("List: < ");
current = head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(list_a, i);
// test length
printf("Length of list = %d\n", length(list_a));
// test print head list
printf("head:\n");
printList(list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(list_a, i);
// test print head list
printf("head(append):\n");
printList(list_a);
// make a copy of list
list_a_copy = copyList(list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(list_a));
// test print copy list
printf("head copy:\n");
printList(list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(list_a_copy));
}
Thank you for you help. I'm still learning these C pointers, and I know I'm close.
Cheers
I looked into function push():
void push(struct node* head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = head;
head = new_ptr;
}
The way you assign head = new_ptr; is wrong. Doing so only, head has effect within in the function, head won't be pointed to the memory you allocated after push() is called. So you need to fix your push() function:
void push(struct node **head, int data) {
if ((*head) == null)
(*head) = (struct node*)malloc(sizeof(struct node));
(*head)->data = data;
(*head)->next = head;
}
The problem is that you are passing a pointer to a node in your methods. This means that what you are modifying is a local parameter and not what you are passing to the method. Why is this? Because passing by value copies the parameter, to the address is directly copied.
struct Node *list_a = NULL;
push(list_a, 5);
When you call push, what happens is that a copy of the variable list_a is pushed onto the stack and then the function is called. The same thing, if you think about it, happens with simple cases:
int x = 5;
add(x, 5);
void add(int a, int b) { a += b; } // <-- this won't modify the x passed
So here
void push(struct Node *head, int value) {
head = something;
}
you are not modifying the original list_a but rather a copy of it which has been passed to the function.
To be able to modify the original pointer you need to pass the address to it, so a pointer to the pointer of the head of the list. This can be done easily:
struct Node *list_a = NULL;
push(&node, 5);
void push (struct Node **node, int value) {
...
*node = malloc(..);
}
So here the address of the variable list_a is passed to the function, dereferencing it allows you to modify the real value instead that just a copy.

Resources