my linked list code is not printing the last node can you please help me where I am getting it wrong
I tried do while it didn't work
i don't want to make head node separate therefor please don't tell me change the whole code
how do i free allocated memory of the whole code
last how can i use recursion for display
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data ;
struct node *next;
}node;
int create(int n);
void display(node* head);
int main()
{
int n;
node* HEAD = NULL;
scanf("%d",&n);
HEAD=create(n);
display(HEAD);
return 0;
}
int create(int n)
{
int i;
node * head=NULL;
node * temp=NULL;
node * p = NULL;
for(i=0;i<n;i++)
{
temp =(node*)malloc(sizeof(node));
scanf("%d",&(temp->data));
temp->next= NULL;
if(head==NULL)
{
head=temp;
}
else
{
p=head;
while(p->next != NULL)
{
p=p->next;
}
p->next=temp;
}
}
return head;
}
void display(node* head)
{
node* p= head;
while(p->next != NULL)
{
printf("\n data: %d",p->data);
p=p->next;
}
}
At the time the condition in the while loop fails, you still haven't checked the last node you're in. You dereferenced it at the end of the last iteration, but you never printed the data inside. A quick fix would be to just print the current node's data after the loop exits:
while(p->next != NULL)
{
printf("\n data: %d",p->data);
p=p->next;
}
printf("\n data: %d", p->data);
This would also fix the issue brought up in the comment on your question. Of course you still want to make sure that the list is not empty before doing this.
Consider the case of a single node linked list. Head->next would evaluate to NULL. And the value of Head would not be displayed. To remedy this move the printf statement up.
EDIT: YOU ALSO MUST ENSURE THAT HEAD IS NOT NULL, otherwise your code will still fail if you make my changes
void display(node* head)
{
node* p= head;
while(p->next != NULL)
{
printf("\n data: %d",p->data);
p=p->next;
}
}
The problem is your while case, you need to change while(p->next != NULL) to while(p != NULL).
The reason for this is because your pointer is on the last element but you are checking his next.
Another thing, change int create(int n) to node * create(int n). You are returning pointer and not the int parameter.
Related
I am trying to implement polynomial addition using linked list. I have only coded a small part of it where i accept the input into first polynomial and while i was testing the code it kept throwing a segmentation fault error. I have sprinkled some random printf statements to try to debug the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
struct node* poly1,poly2,poly3;
void createList(struct node* head){
int ch=0;
struct node* temp;
struct node* newNode = createNode();
head=NULL;
temp=NULL;
while(ch!=-1){
printf("Enter coefficient and power");
scanf("%d",&newNode->coeff);
scanf("%d",&newNode->power);
if( head ==NULL){
printf("123123123");
temp = newNode;
head = newNode;
printf("bbbbbb");
}else{
printf("aaaaaaaa");
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
printf("9999");
}
printf("1");
}
void display(struct node* head)
{
struct node *temp;
temp=head;
if(temp==NULL)
printf("LL not present");
else
{
while(temp!=NULL)
{
printf("%dx^%d ",temp->coeff,temp->power);
temp=temp->next;
}
}
}
void main(){
printf("Enter the data for the first polynomial\n");
createList(poly1);
printf("%d",poly1->coeff);
display(poly1);
}
This is the output i am getting for it-
Enter the data for the first polynomial Enter coefficient and power3 2
123123123bbbbbbEnter -1 to exit9 9999Enter coefficient and power 1 1
1 1 aaaaaaaaEnter -1 to exit-1 Segmentation fault
Interestingly when i change the second last line of my while loop from
scanf("%d",&ch);
to ch=-1; the output that i get has none of the random printf i added to debug :
Enter the data for the first polynomial Enter coefficient and power3 2
Segmentation fault
I dont understand what the difference is between both of these cases. Also whats the issue with segmentation fault being thrown around?
As noted above you need to pass in the address of poly1, I made it a local rather than a global variable. Then you need to create a new node per loop iteration in createList(). Removed debugging output (use a macro and write something sensible in case you want to leave it in). Prefer for to while loops for iteration.
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
void createList(struct node **head){
int ch;
*head = NULL;
do {
printf("Enter coefficient and power: ");
struct node* newNode = createNode();
if(scanf("%d %d",&newNode->coeff, &newNode->power) != 2) {
// TBD: free list
*head = NULL;
printf("scanf failed\n");
return;
}
if(!*head){
*head = newNode;
} else {
(*head)->next = newNode;
}
printf("Enter -1 to exit: ");
if(scanf("%d",&ch) != 1) {
// TBD: free list?
// *head = NULL;
printf("scanf failed\n");
return;
}
} while(ch!=-1);
}
void display(struct node *head)
{
if(!head) {
printf("LL not present");
return;
}
for(; head; head=head->next) {
printf("%dx^%d ", head->coeff, head->power);
}
printf("\n");
}
int main(void){
printf("Enter the data for the first polynomial\n");
struct node *poly1;
createList(&poly1);
display(poly1);
}
and example session:
Enter the data for the first polynomial
Enter coefficient and power: 1 2
Enter -1 to exit: 0
Enter coefficient and power: 3 4
Enter -1 to exit: -1
1x^2 3x^4
Consider reading a char instead of a int for the loop control (newline is continue, and 'q' could be quit). If you separate the UI from data structure manipulation then it will much easier to test your code (non-interactively). Write a function to free your list, and call that in the end. This will allow you to use a tool like valgrind to search for memory leaks.
For the first part of your question, I can't reproduce the issue. I changed the line scanf("%d", &ch); to ch = -1, and my output was: "123123123bbbbbbEnter -1 to exit99991", which does not match your output. Are you sure that your code compiled correctly?
For the second part of your question, the reason why you are getting a segment fault, is because you are not actually creating a new node for every polynomial. You only have one instance of a node, and in the while-loop, you constantly change the attributes of that node. In order for this to work, you have to create a new node for every polynomial, and insert that node into the list.
Some stylistic remarks:
It makes more sense to immediately assign a variable when you declare it. For example, in your code it happens a lot that you create a variable like this: int num;, and on the next line: num = 5;, for different datatypes and values. It makes more sense to immediately write: int num = 5;.
You declared poly1, poly2 and poly3, but you are only using poly1. You declared these variables globally, and then changed the contents of poly1 in a function. In order to optimally scope your variables, it makes more sense to write: struct Node *poly1 = createList();.
The code with these remarks implemented looks like this:
#include <stdio.h>
#include <stdlib.h>
struct Node {
struct Node* next;
int coeff;
int power;
};
struct Node* createNode(){
struct Node *head = malloc(sizeof(struct Node));
//error check if malloc failed.
if(head == NULL) {
exit(-1);
}
printf("Enter coefficient and power\n");
scanf("%d %d", &head->coeff, &head->power);
head->next = NULL;
return head;
}
struct Node *createList(){
int ch=0;
struct Node* head = NULL;
struct Node* temp = NULL;
while(ch != -1){
struct Node* newNode = createNode();
if(head == NULL) {
head = newNode;
temp = newNode;
} else {
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
}
return head;
}
void display(struct Node* head) {
while(head != NULL) {
printf("%dx^%d ",head->coeff,head->power);
head=head->next;
}
}
I am trying to return the head of a linked list in the function Insert of the following program. However, it is failing with compilation error.
Can anyone please tell me what wrong I have done:
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int data;
struct ListNode *next;
};
int ListLength(struct ListNode *head)
{
int count = 0;
struct ListNode *temp=head;
while(temp!=NULL)
{
count++;
temp=temp->next;
}
return count;
}
struct ListNode *Insert(struct ListNode *head, int value, int pos)
{
struct ListNode *temp,*curr;
curr=head;
int k=1;
temp=(struct ListNode *)malloc(sizeof(struct ListNode));
if(pos==1)
{
temp->data=value;
if(head==NULL)
{
temp->next=NULL;
head=temp;
}
else
{
temp->next=head;
head=temp;
}
}
else
{
while((curr!=NULL) && (k<pos))
{
k++;
curr=curr->next;
}
temp->data=value;
temp->next=curr->next;
curr->next=temp;
}
return head;
}
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next;
}
}
int main
{
struct ListNode *head=NULL;
//head = NULL;
head=Insert(head,10,1);
//Insert(head,11,2);
printList(head);
return 0;
}
I am trying to return the head of the new linked list after the insertion. I don't know where I am going wrong. Thanks in advance for the help.
(i) Firstly, include int main(void) as mentioned in the comments.
(ii) Next, with your current code, when you try printing the list, you are going to be in an infinite loop and get a stack overflow.
To avoid this, increment the temp to point to the next node after each print.
So your print function should look like:
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next; // this line is required
}
}
(iii) And in your main function, call the printList with an argument, that is the head of the node like this:
printList(head);
(iv) And don't forget to return the count in your finding the length of the list function. Add the return statement at the end of your ListLength function:
return count;
(v) Your current code does not handle a case when head is NULL, and user wants to insert at a position greater than 1. Or more generally, when a user wants to insert at a position that is greater than the current list's length.
While you trust such an input would not be given, always handle such exceptions (you would probably get a SEGMENTATION FAULT here when trying to access memory of null nodes).
To handle this, you can add a check at the start of the Insert function like,
int lenList = ListLength(head);
if (lenList < pos)
{
printf("Please provide a position less than %d to insert", lenList);
return 0; // don't proceed with inserting node with NULL pointers
}
If head is declared global you don't have to return it. (Sorry, my answer is short)
I am having a tough time deleting all members in a linked in a single function. If I break it up like you see below, it works fine, but this seems wildly inefficient and want to figure out the correct way to do this. in order to free all nodes I need to have function to first free all nodes other then the head, then have a function free the head link. this seems like it would be easy to do but I am having trouble.
Thanks for the help!
int main() {
struct node *head = NULL;
createList(&head);
//do stuff with list
freeListMembers(head);
freeListHead(&head);
return 0;
}
int createList(struct node **head) {
//create list
return 0;
}
void freeListMembers(struct node *head){
while(head->next != NULL){
head->next = NULL;
free(head->next);
}
return;
}
void freeListHead(struct node **head) {
*head = NULL;
free(*head);
return;
}
here is the code that I want to work but does not. the issue I am seeing is a an error for "*head->next;" where it sais "expression must have pointer to struct or union type"
int main() {
struct node *head = NULL;
createList(&head);
//do stuff with list
freeAllListMembers(&head);
return 0;
}
int createList(struct node **head) {
//create list
return 0;
}
void freeAllListMembers(struct node **head){
while (head != NULL) {
struct node *temp = *head->next;
free(*head);
*head = temp ;
}
return;
}
From your code :
void freeListMembers(struct node *head){
while(head->next != NULL){
head->next = NULL;
free(head->next);
}
return;
}
This is freeing NULL, not your node*.
Freeing the list is as simple as using a temporary pointer to the next node.
while (head) {
node* next = head->next;
free(head);
head = next;
}
From your edit :
void freeAllListMembers(struct node **head){
while (head != NULL) {
struct node *temp = *head->next;
free(*head);
*head = temp ;
}
return;
}
There are a couple errors with this. It should be while (*head != NULL) and (*head)->next. The first is a logic error, because head will always be non-NULL, and the second is a syntax error, because you need to dereference the head pointer before accessing the next pointer.
This will work. You just set next of head to null and freed head. Now we can not move to second element.So we wont be able to free the nodes.Also check base condition. I hope it helps
void freeListmembers(node *head){
node *temp=head;
if(head==NULL)//Base condition
return;
while(head->next!=NULL){
temp=head;//Moved temp to head. we will move head to next and free the previous node
head=head->next;
free(temp);
}
free(head);
return;
}
While inserting node at end in linked list ,my code is running in infinite loop.
IDE Used-Eclipse
64 bit OS
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int info;
struct Node *next;
}node;
node *head;
node *ptr1;
void insert(int x);
void show();
int main()
{
int i,x,n;
puts("Enter number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
puts("Enter elements");
scanf("%d",&x);
insert(x);
}
show();
return 0;
}
//To insert the data in linked list
void insert(int x)
{
node *ptr;
ptr1=head;
ptr=(node*)malloc(sizeof(node));
ptr->info=x;
if(head==NULL)
{
ptr->next=head;
head=ptr;
}
else
{
ptr1->next=NULL;
ptr1=ptr;
}
}
//To print the details of list
//Unable to figure out this function
void show()
{
while(ptr1->next!=NULL)
{
printf("%d\n",ptr1->info);
ptr1=ptr1->next;
}
}
The ptr1 is set to head each time your code enters the insert function then setting it to ptr in the else subsection but nothing pointing to any previous items.
Here is an example in case you need one.
typedef struct Node
{
int info;
struct Node *next;
}node;
node *head = NULL;
void insert(int x);
void show();
int main()
{
int i,x,n;
puts("Enter number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
puts("Enter elements");
scanf("%d",&x);
insert(x);
}
show();
return 0;
}
void insert(int x)
{
node *ptr = (node*)malloc(sizeof(node));
ptr->info=x;
ptr->next=head; /* this will always add the new entry at the beginning of the list all you need it to initialize the head to NULL*/
head = ptr; /* move the head so that it points to the newly created list element */
}
void show()
{
node *ptr1 = head;
printf("%d\n",ptr1->info); /* print the head */
while(ptr1->next!=NULL) /* now walk the list remember it first looks if the next pointer in the list is null first then it jumps on next element in case it is not*/
{
ptr1=ptr1->next;
printf("%d\n",ptr1->info);
}
}
Remember to create a function to free up the list elements before exiting the main.
Your two functions can be simplified. A singly linked list is very easy to implement. I would also improve the functions by taking the list pointer as an argument, and in the case of insert() return the new head of the list: but get it working first! Note there is no reason or need to declare global variables when their only use is local to a function.
// insert new node at head of the list
void insert(int x) {
node *ptr = malloc(sizeof(node));
if (ptr == NULL) {
printf ("malloc failure\n");
exit (1);
}
ptr->info = x;
ptr->next = head; // append existing list
head = ptr; // new head of list
}
// show the linked list
void show() {
node *ptr = head; // start at head of list
while (ptr != NULL) {
printf("%d\n", ptr->info);
ptr = ptr->next; // follow the link chain
}
}
EDIT here is code to add to the tail of a linked list
// insert new node at tail of the list
void insert2(int x) {
node *tail = head;
node **last = &head;
node *ptr;
while (tail) {
last = &tail->next;
tail = tail->next;
}
ptr = malloc(sizeof(node));
if (ptr == NULL) {
printf ("malloc failure\n");
exit (1);
}
ptr->info = x;
ptr->next = NULL;
*last = ptr;
}
There's nothing wrong when i built the program in both VS & codeblock. While, when i ran it, it either broke after i typed in the index number or just show letters infinitely...
#include<stdio.h>
#include<stdlib.h>
// list_node structure
typedef struct list_node{
int item;
struct list_node *next;
}ListNode;
//call functions that will be used
void printNode(ListNode *head);
int removeNode(ListNode **ptrhead, int index);
ListNode *findNode(ListNode *head, int index);
int main(){
int index,value;
ListNode *head=NULL;
ListNode *temp;
//build the list
printf("Enter a value:");
scanf("%d",&value);
do{
temp->item=value;
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
}
else{
temp->next=(struct list_node *)malloc(sizeof(ListNode));
temp=temp->next;
}
printf("Enter a value:");
scanf("%d",&value);
}while(value!=-1);
printf("Enter the index: ");
scanf("%d",&index);
// remove the node at the position indexed
// when I used debugger, I saw it didn't execute this step. Maybe there's something wrong with it....
removeNode(&head,index);
printNode(head);
return 0;
}
void printNode(ListNode *head){
if (head==NULL)
exit(0);
while(head!=NULL){
printf("%d",head->item);
head=head->next;
}
printf("\n");
}
ListNode *findNode(ListNode *head,int index){
if(head==NULL||index<0)
return NULL;
while(index>0){
head=head->next;
index--;
}
return head;
}
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur,*temphead;
temphead=*ptrhead;
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
cur=pre->next;
temphead->next=cur;
return 0;
}
else
return -1;
}
prev=NULL;
cur=head;
/* traverse the list until you find your target */
while (cur != NULL && cur->id != search_id) {
prev=cur;
cur=cur->next;
}
/* if a result is found */
if (cur != NULL) {
/* check for the head of the list */
if (prev == NULL)
head=cur->next;
else
prev->next=cur->next;
/* release the old memory structure */
free(cur);
}
Whats up dude....I hope u will get it... :)
temp->item=value; - you're dereferencing temp when it's uninitialized. Undefined behavior, crash and burn.
In your loop,
temp->item=value;
No space has been allocated to temp. Hence, this will crash !!
if(head==NULL){
head=(struct list_node *)malloc(sizeof(ListNode));
temp=head;
Typically, you woud allocate a temp node and assign it to head as head = temp. Another point which is missing is when a new node is created, the next should be initialized to NULL as temp->next = NULL
In removeNode,
if(findNode(temphead,index)!=NULL){
pre=findNode(temphead,index);
pre will be pointing to the node to be removed, but temphead will still be pointing to head of the list. findNode will not modify the temphead. So tmphead->next = cur will modify the head always
int removeNode(ListNode **ptrhead,int index){
ListNode *pre,*cur;
if (index==-1)
return 1;
else if(findNode((*ptrhead),(index))!=NULL){
pre=findNode((*ptrhead),(index-1));
cur=pre->next;
pre->next=cur->next;
return 0;
}
else
return 1;
}
I modified the last part and addedtemp->next=NULLin the main function. this program can ran well now!