Double Linked List query - c

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.

Related

Why does my code skip over certain nodes?

I'm writing this code to store data records of students' first name, last name, scores and zip codes. I have almost everything done but my Print() function doesn't print the first element of node 2(first name of 2nd student) and turns into an infinite loop when I input ore than 2 nodes, what am i doing wrong?
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
void Insert(char first[20], char last[20], float data, char zip[50]);
void delete(int e);
void Print();
double median();
struct node
{
char first_name[20];
char last_name[20];
float score;
char zip_code[50];
struct node *ptr;
};
int n;
struct node* head =NULL;
struct node* tail=NULL ;
void Insert(char first[20], char last[20], float data, char zip[50])
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp->ptr=NULL;
strcpy(temp->first_name,first);
strcpy(temp->last_name,last);
temp->score=data;
strcpy(temp->zip_code,zip);
if(head==NULL)
{
head=temp;
tail=temp;
return;
}
tail->ptr=temp;
tail=temp;
free(temp);
temp=NULL;
}
void delete(int e)
{
int i;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
if(e==1)
{
head=temp->ptr;
free(temp);
return;
}
else if(e==n)
{
while(temp->ptr->ptr!=NULL)
{
temp=temp->ptr;
}
temp->ptr=NULL;
free(temp->ptr);
return;
}
for(i=0; i<(e-2); ++i)
temp=temp->ptr;
struct node *temp1=temp->ptr;
temp->ptr=temp1->ptr;
free(temp1);
}
void Print()
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
printf("Data entered is below: \n");
while(temp!=NULL)
{
printf("First Name: %s, Last Name: %s, Score: %.2f, Zip Code: %s",temp->first_name,temp->last_name,temp->score,temp->zip_code);
temp=temp->ptr;
printf("\n");
}
printf("\n\n\n");
}
double median()
{
double median,tmp;;
double *ex=(double*)malloc(sizeof(double));/*head*/
double *exe=(double*)malloc(sizeof(double));/*dynamic*/
ex=exe;
int i=1,term,j;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
while(i<=n)
{
temp->ptr;
*exe=temp->score;
exe++;
}
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if( *(ex+i) > *(ex+j))
{
tmp = *(ex+i);
*(ex+i) = *(ex+j);
*(ex+j) = tmp;
}
}
}
if(n%2==0)
{
/*even;median=n/2-1*/
term=(n/2)-1;
median= (*(ex+(term-1)));
return median;
}
/*odd; median=n-1/2*/
term=(n-1)/2;
median= (*(ex+(term-1)));
return median;
}
int main()
{
char name1[20],name2[20], code[50];
float x;
int i,option,index;
printf("Enter the number of nodes: ");
scanf("%d",&n);
printf("Please enter the records of students in the following format(click enter for new students)\n");
printf("First_Name Last_Name Score Zip_Code\n");
for(i=1; i<=n; ++i)
{
scanf(" %s",name1);
scanf(" %s",name2);
scanf(" %f",&x);
scanf(" %s",code);
Insert(name1,name2,x,code);
}
printf("\n");
while(1)
{
printf("Choose one of the following options: \n");
printf("Print records (press 1)\nAdd a new record (press 2)\nDelete record(s) (press 3)\nSearch by zip code (press 4)\nSearch by score range (press 5)\nFind median score (press 6)\nExit the program (press 0)\n");
scanf("%d",&option);
switch(option)
{
case 0:
{
/*Exit Program*/
exit(0);
break;
}
case 1:
{
/*print*/
Print();
break;
}
case 2:
{
/*insert*/
getchar();
printf("Enter the new record in the following format: \nFirst_Name Last_Name Score Zip_Code\n");
scanf("%s",name1);
scanf("%s",name2);
scanf("%f",&x);
scanf("%s",code);
getchar();
Insert(name1,name2,x,code);
break;
}
case 3:
{
/*delete*/
printf("Enter the node/record to be deleted: ");
scanf("%d",&index);
delete(index);
printf("The deletion of record %d has been succesfully completed!\n\n",index);
break;
}
case 4:
{
/*search by zip*/
break;
}
case 5:
{
/*search by score*/
break;
}
case 6:
{
/*find median*/
printf("Median score for the entered records is: %f",median());
break;
}
}/*switch*/
}/*while*/
return 0;
}
The Insert function is holding a reference to freed data:
tail=temp;
free(temp);
Attempting to use the storage referenced by tail after it's been freed is an error.

Finding path between nodes using BFS in C language

I'm new to C language and it's been harder for me to work with pointers after working in Java😥
I was trying to write a code of finding a path (not necessary minimum) between two nodes in a graph using breadth-first-search.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 200
void push(int a);
int pop(void);
void bfs(int a,int b,int len);
int nextnode(int a);
typedef struct node{
int data;
struct node* next;
}node;
int res[MAXSIZE];
int visited[MAXSIZE];
int rear,front;
node* graph[MAXSIZE];
int len;
int path[MAXSIZE];
int nextnode(int a)
{
if(graph[a]==NULL)
return -1;
else
{
struct node* c=graph[a];
while(visited[c->data]!=1 && c!=NULL)
{
c=c->next;
}
if(c==NULL)
return -1;
else
return c->data;
}
}
void push(int a)
{
path[rear]=a;
rear++;
}
int pop()
{
if(front==rear)
return -1;
int num=path[front];
front++;
return num;
}
int main()
{
rear=0;
len=0;
front=0;
int n,e;
int i,a,b;
printf("%s\n%s", "Inputting Graph... ","Enter number of nodes and edges: ");
scanf("%d %d",&n,&e);
printf("%s %d %s\n", "Graph Created with",n,"nodes without any edge.");
printf("%s\n","Enter the edges in 1 2 format if an edge exist from Node 1 to Node 2" );
for(i=1;i<=n;i++)
{
graph[i]=NULL;
visited[i]=0;
}
struct node* new = (struct node*)malloc(sizeof(struct node));
for(i=0;i<e;i++)
{
scanf("%d %d",&a,&b);
new->data=b;
new->next=NULL;
struct node* curr=graph[a];
if(curr==NULL)
{
graph[a]=new;
}
else
{
while(curr->next!=NULL)
{
curr=curr->next;
}
curr->next=new;
}
}
printf("%s\n", "Graph Created Successfully.");
printf("%s", "Enter the node numbers between which the path is to be found between: ");
scanf("%d %d",&a,&b);
bfs(a,b,0);
printf("Length is %d\n",len);
for(i=1;i<=len;i++)
{
printf("%d\n",res[len]);
}
}
void bfs(int a,int b,int len)
{
int c;
visited[a]=1;
int flag=0;
while(a!=-1)
{
c=nextnode(a);
while(c!=-1)
{
c=nextnode(a);
if(c==b)
{
flag=1;
break;
}
push(c);
visited[c]=1;
}
len++;
res[len]=a;
if(flag==1)
{
res[len]=b;
break;
}
a=pop();
}
}
I know it's huge, but please mind going through it once. The problem I'm getting is Segmentation Fault after I input all the values, and before dfs() function call! Please Help.
For understanding: I have used array of Lists. Each array index denotes a node and the list denotes all the edges it is connected to. eg: if my Graph has 1->2, 1->3, 2-3 edges;
graph[1] will have a list 2->3->NULL. And graph[2] will have 3->NULL.
Thank you.
EDIT
As pointed out by Aditi, the error was in the line where nextnode function ran the while loop. After changing the code to
while(c != NULL && visited[c->data] == 1 )
the program ran flawlessly.
Thanks!
I think what you are trying to do is not graph[i] = NULL but graph[i]->next = NULL

Converting a Binary tree to a Binary Search Tree

So here I'm converting a Binary Tree to a Binary Search Tree by copying the elements of the tree to an array.
Then,I'm sorting the array(bubble sort) and then traversing the tree using inorder traversal and copying the elements of the array to the tree.
Everything is working fine but the function void inr(Node *root) is not copying the elements as in a binary search tree I should get elements in the increasing order(inorder traversal) but I'm not getting a proper output.
#include<stdio.h>
#include<stdlib.h>
int x=0;
int l=0;
typedef struct node
{
int data;
struct node *rlink;
struct node *llink;
} Node;
Node *getnode()
{
Node *temp=(Node *)malloc(sizeof(Node));
return temp;
}
int a[10];
int i=0;
Node *create(Node *root,int key)
{
int c;
if(root==NULL)
{
root=getnode();
root->rlink=root->llink=NULL;
root->data=key;
}
else
{
printf("Enter where you want to enter 1.RIGHT 2.LEFT");
scanf("%d",&c);
switch(c)
{
case 1:root->rlink=create(root->rlink,key);
break;
case 2:root->llink=create(root->llink,key);
break;
default:printf("Wrong choice");
break;
}
}
return root;
}
void inorder(Node *root) //to copy the contents of the tree in the array
{
if(root!=NULL)
{
inorder(root->rlink);
if(root->data>0) a[i++]=root->data;
inorder(root->llink);
}
}
void utu(Node *h) //For inorder traversal
{
if(h!=NULL)
{
utu(h->rlink);
printf("%d",h->data);
utu(h->llink);
}
}
void inr(Node *root) //to copy the elements of sorted array in the tree to make it a BST
{
if(root==NULL) return;
else if(root!=NULL)
{
inr(root->llink);
root->data=a[l++];
inr(root->rlink);
}
}
void main()
{
int j=0;
int temp=0;
Node *h=NULL;
h=create(h,5);
h=create(h,6);
h=create(h,7);
h=create(h,8);
inorder(h);
count(h);
printf("%d \n",x);
printf("\n \n \n");
for(j=0;j<x;j++)
{
printf("%d \n",a[j]);
}
for(int i=0;i<x;i++) //bubble sorting of the array obtained by copying the nodes data in the array
{
for(j=i+1;j<x;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
utu(h);
//for(j=0;j<x;j++)
//{
// printf("\n %d \n",a[j]);
//}
printf("\n \n");
//j=maxd(h);
//printf("%d",j);
inr(h);
utu(h);
}

N-polynomial addition not working

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

Implementing BinarySearchTree using Single Linked List

I have the below code which I am using to implement BinarySearchTree. Somehow it doesn't build the binarytree.Can anybody help what is the issue ?
typedef struct BinarySearchTree
{
struct BinarySearchTree *left;
int nodeval;
struct BinarySearchTree *right;
}
BST;
BST *root=NULL;
void addrootnode(BST *,int );
void addnode(BST *,int );
void deletenode(int );
void printnodes();
main()
{
int nodeval;
char choice;
printf("\n r->rootnode \n a->add \n d->delete \n p->print \n e->exit\n");
while (1)
{
printf("\nEnter your choice:");
scanf("%c",&choice);
switch (choice)
{
case 'r':
printf("\nEnter the root node value to add: ");
scanf("%d",&nodeval);
addrootnode(root,nodeval);
break;
case 'a':
printf("\nEnter the node value to add: ");
scanf("%d",&nodeval);
addnode(root,nodeval);
break;
case 'd':
printf("\nEnter the node value to delete: ");
scanf("%d",&nodeval);
break;
case 'p':
//printf("\n");
printnodes(root);
break;
case 'e':
exit(0);
default:
break;
}
}
getchar();
}//end of main
//addrootnode
void addrootnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
root=ptr;
}
}
//add node
void addnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
}
else if(num < ptr->nodeval )
{
addnode(ptr->left,num);
}
else
{
addnode(ptr->right,num);
}
}
//delete functionality
void deletenode(int nodeval)
{
}
//print all nodes
void printnodes(BST *ptr)
{
if (ptr)
{
printnodes(ptr->left);
printf("%d\t",ptr->nodeval);
printnodes(ptr->right);
}
}
You should not use BST *ptr as argument to addnode. You try to assign a value to it but at this time ptr is a local variable to the function addnode an does not alter the intended left or right pointer of the parent node.
Try to think about using BST **ptr instead.

Resources