N-polynomial addition not working - c

I'm not sure if I'd sound dumb, but still..I want to develop a program using linked list where I could add upto 5 Polynomials. The code I could come up with is..
struct node
{
int exp,coeff;
struct node *next;
} *start[5]={NULL};
void read()
{
struct node *current,*newnode;
int n,i,max,j;
printf("How many poly?");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nDetails of poly %d\n",i);
printf("Max degree:");
scanf("%d",&max);
for(j=max;j>=0;j--)
{
newnode=(struct node *)malloc(sizeof(newnode));
printf("\nEnter coeff of %d:",j);
scanf("%d",&newnode->coeff);
newnode->exp=j;
if(start[i]==NULL)
{
printf("a%d",start[i]);
start[i]=newnode;
newnode->next=NULL;
printf("%d,%d",start[i],start[i]->next);
}
else if(start[i]->next==NULL)
{
printf("b");
start[i]->next=newnode;
newnode->next=NULL;
printf("%d",start[i]);
}
else
{
printf("c");
current=start[i];
while(current->next!=NULL)
current=current->next;
current->next=newnode;
newnode->next=NULL;
printf("%d",start[i]);
}
}
}
}
void sum()
{
struct node *curr1,*curr2,*tmp;
int i,co,ex;
curr1=start[0];
while(curr1!=NULL)
{
for(i=1;i<5;i++)
{
co=0;
if(curr1==start[i])
tmp=start[i];
else
tmp=tmp->next;
curr2=tmp;
if(curr1->exp==curr2->exp)
{
if(co==0)
co=co+curr1->coeff+curr2->coeff;
else
co=co+curr2->coeff;
ex=curr1->exp;
break;
}
else if(curr1->exp>curr2->exp)
{
ex=curr1->exp;
if(co==0)
co=co+curr1->coeff;
else
break;
}
else
{
ex=curr2->exp;
if(co==0)
co=co+curr2->coeff;
else
break;
}
}
printf("%dX^%d",co,ex);
curr1=curr1->next;
}
}
int main()
{
read();
printf("result:\n");
sum();
getch();
return 0;
}
But on executing,only the first polynomial is getting read.ie, 'i' loop work only once. I tried to check my read function and notice the second condition was not working.ie,this one:
else if(start[i]->next==NULL)
{
printf("b");
start[i]->next=newnode;
newnode->next=NULL;
printf("%d",start[i]);
}
That print b was to check if program entered this block LOL.
Somebody help me with this please...

This part
newnode=(struct node *)malloc(sizeof(newnode)); // This will allocate space for
// a pointer to struct node
should be
newnode=(struct node *)malloc(sizeof(struct node)); // This will allocate space for
// a struct node
or better as suggested by #chux
newnode = malloc(sizeof *newnode); // This will allocate space for
// whatever newnode points to. In
// this case a struct node
Not sure it makes a difference but I would change:
start[5]={NULL};
into
start[5]={NULL, NULL, NULL, NULL, NULL};

Related

C language:Binary search tree with strings

I have to create a program for a binary search tree for strings, which calculates how many times each word repeats, and it seems like I can't get the program to do as intended, because when printing it out, what should be printed first, are the words/characters smaller than the origin node, followed by the words/characters bigger than the origin node. But what my program does, it just prints it out in the order that I introduced the words/characters, I am still thinking about, how to realise the part of the program that will calculate the number of appearances of each word.
#include<stdio.h>
#include<stdlib.h>
#define MAX 15
typedef struct BST
{
char data[MAX];
struct BST *left;
struct BST *right;
} node;
node *create();
void insert(node *,node *);
void preorder(node *);
int main()
{
char ch;
node *root=NULL,*temp;
do
{
temp=create();
if(root==NULL)
{
root=temp;
}
else
{
insert(root,temp);
}
printf("\nDo you want to enter more(y/n)?");
ch=getch();
}
while(ch=='y'||ch=='Y');
printf("\nPreorder Traversal: ");
preorder(root);
return 0;
}
node *create()
{
node *temp;
printf("\nEnter data:");
temp=(node*)malloc(sizeof(node));
fgets(&temp->data,MAX,stdin);
temp->left=temp->right=NULL;
return temp;
}
void insert(node *root,node *temp)
{
if(temp->data<root->data)
{
if(root->left!=NULL)
insert(root->left,temp);
else
root->left=temp;
}
if(temp->data>root->data)
{
if(root->right!=NULL)
insert(root->right,temp);
else
root->right=temp;
}
}
void preorder(node *root)
{
if(root!=NULL)
{
printf("%s ",root->data);
preorder(root->left);
preorder(root->right);
}
}
Here's what I came up with, with the help of somebody in the comments, and it works as intended
void insert(node *root,node *temp)
{
int cmp_rezult=strcmp(temp->data,root->data);
printf("\nCompare:%d ", cmp_rezult);
if(cmp_rezult<0)
{
if(root->left!=NULL)
insert(root->left,temp);
else
root->left=temp;
}
if(cmp_rezult>0)
{
if(root->right!=NULL)
insert(root->right,temp);
else
root->right=temp;
}
}
In insert you do:
temp->data<root->data
but that's not how you compare strings in C.
To compare strings use strcmp
Further it seems that insert miss a code block for handling "equal".
So something like:
int cmp_result = strcmp(temp, data<root->data);
if (cmp_result < 0)
{
// Handle less than
}
else if (cmp_result > 0)
{
// Handle greater than
}
else // i.e. cmp_result == 0
{
// Handle equal
}

Double Linked List query

so i have created a program which uses double linked list and
performs some operations on it . The problem is that it displays garbage
values
at the end every time i try to create a linked list and then display it.
whats wrong in my code?(sorry! for the bad indentations)
if the linked list i created has elements say 15 and 16, it displays it as
15 16 25710 0 0
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct dll
{
int data;
struct dll *llink;
struct dll *rlink;
};
typedef struct dll *node;
node head=NULL;
void create();
int search(int u);
void insert(int num1);
void Delete(int num2);
void display();
node getnode();
int main()
{
int i,num,o;
while(1)
{
printf("\n1.create a list\n 2. insert before a search node\n 3. delete a node\n 4.display\n 5.exit\n");
scanf("%d",&num);
switch(num)
{
case 1 :
create();
break;
case 2 :
printf("enter the value before which you want to enter the node\n");
scanf("%d",&i);
insert(i);
break;
case 3 :
printf("enter the value to be deleted\n");
scanf("%d",&o);
Delete(o);
break;
case 4 :
printf("the linked list has :\n");
display();
break;
case 5 :
getch();
exit(1);
default :
printf("enter the correct option\n");
break;
}
}
}
node getnode()
{
node temp1;
temp1=(node)malloc(sizeof(node));
temp1->llink=NULL;
temp1->rlink=NULL;
return temp1;
}
void create()
{
node nn;
int num,y;
if(head==NULL)
head=getnode();
while(1)
{
printf("enter the data for the node");
scanf("%d",&num);
head->data=num;
printf("do you want to create another node(1/0):\n");
scanf("%d",&y);
if(y==1)
{
nn=getnode();
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
break;
}
}
void insert (int num1)
{
int i,n,k;
node temp=head,nn;
n=search(num1);
if(n==0)
{
printf("element not present in the linked list");
}
if(n==1)
{
nn=getnode();
printf("enter the data for the node");
scanf("%d",&k);
nn->data=k;
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
{
for(i=2; i<=n; i++)
temp=temp->rlink;
nn=getnode();
temp->llink->rlink=nn;
nn->llink=temp->llink;
nn->rlink=temp;
temp->llink=nn;
}
}
void Delete(int num2)
{
node temp=head;
int p,i;
p=search(num2);
if(p==0)
{
printf("no element is found");
}
if(p==1)
{
printf("the deleted element is %d",head->data);
head=head->rlink;
head->llink=NULL;
free(temp);
}
else
{
for(i=2; i<=p; i++)
{
temp=temp->rlink;
}
temp->llink->rlink=temp->rlink;
temp->rlink->llink=temp->llink;
free(temp);
temp=temp->rlink;
}
}
int search(int u)
{
node temp=head;
int pos=0;
if(u==head->data)
return 1;
else
{
while(temp!=NULL)
{
pos++;
if(temp->data==u)
{
printf("element found\n");
return(pos);
}
temp=temp->rlink;
}
}
if(temp==NULL)
{
return 0;
}
return -1;
}
void display()
{
node temp=head;
while(temp!=NULL)
{
printf("%d\n",temp->data);
temp=temp->rlink;
}
}
This:
temp1=(node)malloc(sizeof(node));
is a major error. Since you're "hiding a star", and node is a typedef for a pointer type, you're not allocating enough memory. It should be:
node temp1 = malloc(sizeof *temp1);
But I really recommend against typedefing a pointer away, it just makes things confusing.

Printing and Deleting queue in C

I'm trying to write a program that enqueue, dequeue, delete a chosen number and print the list. I have problems with the dequeue that i think is because of the menu part when you write a number, I've tried to fix it but the it removes the last number and not the first. The print shows the wrong number and when I tried to solve that problem I got the same problem as I had in dequeue. It's sometinhg wrong in delete but i cant figure it out.
I appreciate all the help i can get
edit:
I've changed it a lot and now everything else works except delete. I want delete to find the number i enter and delete it.
queue.c
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
struct node
{
int info;
struct node *ptr;
int next;
}*first, *last, *temp, *first1;
void enq(int data);
void deq();
void empty();
void display();
void create();
void delete_queue();
int count = 0;
void main()
{
int no, ch;
printf("\n 1 - Enqueue");
printf("\n 2 - Dequeue");
printf("\n 3 - Delete");
printf("\n 4 - Display");
printf("\n 5 - Exit");
create();
while (1)
{
printf("\n Enter choice : ");
scanf_s("%d", &ch);
switch (ch)
{
case 1:
printf("Enter data : ");
scanf_s("%d", &no);
enq(no);
break;
case 2:
deq();
break;
case 3:
printf("Enter data : ");
scanf_s("%d", &no);
delete_queue(no);
case 4:
display();
break;
case 5:
exit(0);
default:
printf("Wrong choice, Please enter correct choice ");
break;
}
}
}
void create()
{
first = last = NULL;
}
void enq(int data)
{
if (last == NULL)
{
last = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = NULL;
last->info = data;
first = last;
}
else
{
temp = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = temp;
temp->info = data;
temp->ptr = NULL;
last = temp;
}
count++;
}
void display()
{
first1 = first;
if ((first1 == NULL) && (last == NULL))
{
printf("Queue is empty");
return;
}
while (first1 != last)
{
printf("%d ", first1->info);
first1 = first1->ptr;
}
if (first1 == last)
printf("%d", first1->info);
}
void deq()
{
first1 = first;
if (first1 == NULL)
{
printf("\n Error: Trying to display elements from empty queue");
return;
}
else
if (first1->ptr != NULL)
{
first1 = first1->ptr;
printf("\n Dequed value : %d", first->info);
free(first);
first = first1;
}
else
{
printf("\n Dequed value : %d", first->info);
free(first);
first = NULL;
last = NULL;
}
count--;
}
void delete_queue()
{
int retval = -1;
if (first)
{
struct node *temp = first;
first = first->next;
if (!first) { last = first; }
retval = temp->next;
free(temp);
}
return retval;
}
void empty()
{
if ((first == NULL) && (last == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
Let me start with a few points of advice about design and style:
I do not recommend this:
typedef struct node {
int data;
struct node *next;
} node;
you are typedefing struct node to node. while it is not illegal, it is confusing. I would recommend
typedef struct _node {
int data;
struct _node *next;
} node;
Additionally, I do not recommend use of global variable with static storage class to keep track of your queue, instead you should create a queue in your main. Use global variables only when you have compelling reasons to do so.
Do remember that when you get rid of your global variable, you will need to rewrite your enqueue dequeue delete etc... functions to take in a queue_c * as parameter (because it wont have access to queueref any more)
Now for the reason that your code is not working properly and #Weather Vane alluded to:
you have a big problem in your delete function.
int delete(int data)
{
int result = 0;
node *curr_ptr; //pointer just created and not initialized
node *prev_ptr; //not initialized
node *temp_ptr; //not initialized
while (curr_ptr != NULL)
//curr_ptr was just created, where is it pointing? fatal error here
{
//inside this block lets imagine curr_ptr is pointing to a valid
//node in the global queue
if (curr_ptr->data == data)
{
result = 1;
if (curr_ptr->next != NULL)
{
temp_ptr = curr_ptr;
//both pointers point to the same thing
destroy_node(temp_ptr);
//now you just destroyed both nodes
prev_ptr->next = curr_ptr->next;
//the first time this block runs prev_ptr is uninitialized
//so prev_ptr->next will most likely seg fault
//this happens for example if you call this function
//for the first time with a long queue
}
else
{
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
//again you are destroying both curr_ptr and temp_ptr
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
return result;
}
}
Perhaps it would be better if you think edge cases very carefully and rethink some of the logic from scratch. (test edge cases as you go)

can anyone find out why is the tree not linking

i am writing a code to create a binary tree but something is going wrong i tried to debug but could not find can anyone find it.
code that i have tried is as follow..
header files are..
#include< stdio.h>
#include< stdlib.h>
structure is..
struct node {
int data;
struct node *left;
struct node *right;
}
other declaration..
*head,*p=NULL;
int count=0;
create() function is..
void create(int m) {
if(count==0)
{
p=(struct node *)malloc(sizeof(struct node));
p->data=m;
p->left=NULL;
p->right=NULL;
head=p;
count++;
}
else {
p=(struct node *)malloc(sizeof(struct node));
p->data=m;
p->left=NULL;
p->right=NULL;
}
}
main function is..
int main()
{
int n,i,m;
scanf("%d",&n);
for(i=0;i<n;i++) {
scanf("%d",&m);
if(i==0) {create(m);}
if(i>0) {
while(1) {
if(m < p->data)
p=p->left;
else
p=p->right;
if(p==NULL)
{
create(m);
break;
}
}
}
p=head;
}
printf("%d",p->left->data); //printing the data
return 0;
}
Think, when i = 1, then count is also 1,
if(m<p->data)
{
p=p->left;
}
what will be happened when p->left is a null? Now p is a null pointer, right? Then you did this...
if(p==NULL)
{
create(m);
break;
}
Lets see, what is happening in create(m). Now in create() else portion will work.
else
{
p=(struct node *)malloc(sizeof(struct node));
p->data=m;
p->left=NULL;
p->right=NULL;
}
It is also OK. Now you have a child of head. Reference of this child is in p. Right? But the mistake which you have done is,
p=head;
That means, what have you done is gone. Now there is no reference of child of head. p is keeping reference of head. See, head->left or head->right is always NULL whatever you keep in p. So you have to create a node where you find a NULL, not in p. It is not giving you any result.
Hope, it will help you. :)

Sorting the numbers in a list / C

I need to sort the numbers that are entered in a list, but I am doing something wrong and it's sorting all of them except the first one.Any ideas how to fix this?
Here's my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* List;
void Add (struct node* p, int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
int main()
{
int n,i,a;
printf("How much numbers are you going to enter? ");
scanf("%d",&n);
for (i=1; i<=n; i++)
{
printf("\nEnter a number: ");
scanf("%d",&a);
Add(List,a);
}
printf("\nThe sorted numbers are: ");
struct node *ptr=List;
while(ptr!=NULL)
{
printf("%d\t",ptr->data);
ptr=ptr->next;
}
printf("\n\n");
system("PAUSE");
return 0;
}
Thanks for the help in advance :-)
in add() function,
if(List==p)
this statement is true for all elements you insert to list since the call to add is,
Add(List,a);
so p=List. therefore the sorting code written in else part is not executed.
Also add statements to check for empty initial list.
You can use code similar to this,
void Add (int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
Since list is a global variable you dont need to pass it to Add() function. change the function call to
Add(a);
void Add (struct node* p, int d){
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else{
q->data=d;
if(List==NULL || List->data < d){//modify this line
q->next= List;//and change NULL to List
List=q;
} else {
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d)){
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
You always call Add with List as the first parameter, so it's alway true inside Add that (List==p). Consequently each new item is just inserted at the front of the list and there is no sorting at all.
EDIT 1
A good practice would be sending a list to the Add routine as a parameter. Or, if you want to keep it external, just don't give it to Add at all and test if(List == NULL)
void Add( int d)
{
// ... alloc 'q' and fill q->d here, then:
if(List == NULL)
{
q->next = NULL;
List = q;
}
else
{
struct node *b; // put q after b
for( b = List; b->next != NULL; b = b->next)
if( b->next->data >= d)
break;
q->next = b->next;
b->next = q;
}
}
EDIT 2
Example of transferring the list to a function by parameter
void Add( struct node **n, int d)
{
// ... alloc 'q' and fill q->d here, then:
while( *n != NULL && (*n)->data < d)
n = & (*n)->next;
q->next = *n;
*n = q;
}
int main()
{
// ...
Add( &List, a);
// ...
}

Resources