How to find the maximum element from the linked list? - c

This is what I have tried so far.
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
void create(struct node **q)
{
struct node *r,*t;
int cnt,i,dat;
printf("How many nodes?");
scanf("%d",&cnt);
for(i=0;i<cnt;i++)
{
printf("Enter the data %d ",i);
scanf("%d",&dat);
r=(struct node *) malloc (sizeof(struct node));
r->data=dat;
r->next=NULL;
if(*q==NULL)
{
*q=r;
}
else
{
t=*q;
while(t->next!=NULL)
{
t=t->next;
}
t->next=r;
}
}
}
void display(struct node **q)
{
struct node *r;
r=*q;
while(r!=NULL)
{
printf("%d->",r->data);
r=r->next;
}
printf("\n");
}
void max(struct node **q)
{
struct node *r;
int max=0;
r=*q;
while((r->next)!=NULL)
{
max=r->data;
r=r->next;
if((r->data)>max)
{
max=r->data;
}
}
printf("The max is %d",max);
printf("\n");
}
int main()
{
struct node *head;
create(&head);
display(&head);
max(&head);
}
If I use the numbers 1, 2, and 3 as input my program currently incorrectly detects 2 as the maximum element. How can I fix it so that it will correctly determine 3 to be the maximum element?
rutuparna#pucsd-rutuparna:~/C/Datastructures assignment$ gcc linkedmax.c
rutuparna#pucsd-rutuparna:~/C/Datastructures assignment$ ./a.out
How many nodes?3
Enter the data 0 3
Enter the data 1 2
Enter the data 2 1
3->2->1->
The max is 2

There are a few issues with the loop
while((r->next)!=NULL) {
max=r->data;
r=r->next;
if((r->data)>max) {
max=r->data;
}
}
The line max=r->data unconditionally updates max. Combining this with the fact that the test (r->next)!=NULL causes your loop to exit one item early, the loop currently always returns the value of the second last item.
The code should be changed to something like
while(r!=NULL) {
if(r->data>max) {
max=r->data;
}
r=r->next;
}

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
}

Single linkedlist creation in C

#include<stdio.h>
#include<stdlib.h>
struct list
{
int a;
int b;
int c;
struct list *next;
};
struct list* addlistele(struct list*,int,int,int);
/* List c element */
void listc()
{
printf(" soon...\n");
}
void printlist(list)
{
struct list* temp;
temp=list;
while(temp!=NULL)
{
printf("a:%d,b;%d,c:%d\n",temp->a,temp->b,temp->c);
temp=temp->next;
}
}
/* List element */
struct list* addlistele(struct list* listadd,int b,int d,int m)
{
int i;
struct list* temp;
struct list* addelement=(struct list*)malloc(sizeof(struct list));
addelement->a=b;
addelement->b=d;
addelement->c=m;
addelement->next=NULL;
if(listadd==NULL)
{
printf("entering");
return addelement;
}
else
{
temp=listadd;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=addelement;
}
return listadd;
}
int main()
{
int ch,i,a,b,c;
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
printf("Choose any one of the option \n");
printf("1.List All \n 2.List c \n");
scanf("%d",&ch);
switch(ch)
{
case 1:printf("Enter values \n");
for(i=0;i<2;i++)
{
scanf("%d %d %d \n",&a,&b,&c);
list=addlistele(element,a,b,c);
}
printlist(list);
break;
case 2:listc(); break;
default:break;
}
}
Hi all, i have written the code like the above one.In that when i gave inputs
> Choose any one of the option
> 1.List All
> 2.List c 1 Enter values 2 3 4 1 2 3
The output is
a:0,b;0,c:0
a:2,b;3,c:4
a:1,b;2,c:3
and also it is not adding the element first i mean it is not entering into this loop
if(listadd==NULL)
{
printf("entering");
return addelement;
}
how to make the head element to be NULL and also i don't know how 0 is coming first.Could anybody can tell me what will be the issue?
In main() you create head element and pass it to the addlistele() function.
element=(struct list*)malloc(sizeof(struct list));
...
list=addlistele(element,a,b,c);
You are seeing this first element which does not have valid values that you expected.
Solution would be you malloc() the element in the function rather than in main() and do not allocate element in main().
replace
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
with
struct list *list=NULL;
then
replace
list=addlistele(element,a,b,c);
with
list=addlistele(list,a,b,c);
Also
replace
void printlist(list)
with
void printlist(struct list *list)
and
replace scanf("%d %d %d \n",&a,&b,&c); with scanf("%d %d %d",&a,&b,&c);

Ascending order in linked list in c

I am trying to do ascending order in linked list through change of links and addresses rather than value
struct node
{
char name[30];
int percent;
struct node *link;
};
int main
{
clrscr();
randomize();
struct node *st;
st=NULL;
for(int i=0;i<7;i++)
append(&st,random(101)); //Assigning random values to structure node->percent
display(st);
AscMarks(&st); //Changing the order of links and addresses to arrange them in ascending order
printf("\nAscending order list...\n");
display(st);
getch();
return 0;
}
/*Adds a node at the end of a linked list */
void append(struct node **q,int per)
{
struct node *temp,*r;
temp=*q;
/* If the list is empty , create first node */
if(temp==NULL)
{
temp=(node*)malloc(sizeof(struct node));
temp->percent=per;
getName(temp->name);
temp->link=NULL;
*q=temp;
}
else
{
while(temp->link!=NULL)
temp=temp->link;
r=(struct node*)malloc(sizeof(struct node));
r->percent=per;
getName(r->name);
r->link=NULL;
temp->link=r;
}
}
/*Displays the contents of the linked list */
void display(struct node *q)
{
while(q!=NULL)
{
printf("%d\t%s\n",q->percent,q->name);
q=q->link;
}
}
void getName(char *c)
{
for(int i=0;i<30;i++)
{
if(i==10||i==20)
*(c+i)=' ';
else
*(c+i)=(char)((random(26)+97));
}
*(c+i+1)='\0';
}
/*To change the links and addresses in order to arrange the percent in ascending order */
void AscMarks(struct node **q)
{
struct node *temp,*temp1,*r;
temp=*q;
// r=q;
for(int i=0;i<7;i++,temp=temp->link)
{ temp1=temp->link;
for(int j=i+1;j<7;j++,temp1=temp1->link)
{
if(temp->percent>temp1->percent)
{
r=*q;
while(r->link!=temp1)
{
r=r->link;
}
r->link=temp1->link;
temp1->link=temp;
temp=temp1;
}
}
if(i==0)
*q=temp;
}
temp->link=NULL;
/*
while(r!=NULL)
{
printf("\n%d",r->percent);
r=r->link;
} */
}
Ascending order (AscMarks) is not giving results as expected and I am unable to see what's my fault in the code Please help
You are not establishing link between the smallest address to the second smallest address and so on ... i have got that through node variable "*s"
by s->link=temp& giving the address of last sorted value (temp) to s..through s=temp.. And in "j" loop after each time , temp->percent> temp1->percent .. you have done temp1-link=temp, it makes the address of temp1, the address of starting temp... means in short ... the number of tries of "j" will be too less to compare all the addresses ... as most of it will repeat ...
so for it you should do j=i;
void AscMarks(struct node **q)
{
struct node *temp,*temp1,*r,*s;
temp=*q;
// r=q;
for(int i=0;i<7;i++,temp=temp->link)
{ temp1=temp->link;
for(int j=i+1;j<7;j++,temp1=temp1->link)
{
if(temp->percent>temp1->percent)
{
r=*q;
while(r->link!=temp1)
{
r=r->link;
}
r->link=temp1->link;
j=i;//resetting the value of j
temp1->link=temp;
temp=temp1;
if(i!=0)
s-link=temp; //establishing link between
//this sorted address(in this loop) to the
//last sorted address
}
}
if(i==0)
*q=temp;
s=temp;//giving it the address of structure which have the last
//sorted value
}
temp->link=NULL; //No need to do this
/*
while(r!=NULL)
{
printf("\n%d",r->percent);
r=r->link;
} */
}

What is wrong with this insertion sort using linked list code in c?

I am getting error while executing this. Compiler does not give any error but when executed it give random output.
What am i doing is taking input from user & storing them to linked list & then implementing insertion sort.
( I am able to call the subroutine insertion sort, so I guess the problem lies within subroutine only)
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node *next;
};
typedef struct node *NODEPTR;
NODEPTR getnode();
NODEPTR insertionSortLinkedList(NODEPTR head);
int main()
{
int i,n,temp;
NODEPTR head,lptr,prevlptr;
printf("No of input integers to be sorted\n");
scanf("%d",&n);
if (n<2){printf("n should be atleast 2 \n");return 0;}
printf("\nType space-separated array of %d integers\n",n);
scanf("%d",&temp);
head=getnode();
head->info=temp;
head->next=NULL;
prevlptr=head;
for (i=0;i<n-1;i++)
{
scanf("%d",&temp);
lptr=getnode();
lptr->info=temp;
prevlptr->next=lptr;
lptr->next=NULL;
prevlptr=lptr;
}
head=insertionSortLinkedList(head);
lptr=head;
while(lptr!=NULL)
{
printf("%d ",lptr->info);
prevlptr=lptr;
lptr=lptr->next;
free(prevlptr);
}
return 0;
}
NODEPTR getnode()
{
NODEPTR p;
p=(struct node*)malloc(sizeof(struct node));
return p;
}
NODEPTR insertionSort(NODEPTR head)
{
NODEPTR listptr,tempptr,prevptr,prevtempptr;
prevptr=head;
listptr=prevptr->next;
while(listptr!=NULL)
{
while (listptr->info < prevptr->info)
{
prevptr->next=listptr->next;
tempptr=head;
prevtempptr=head;
while(tempptr->info <= listptr->info)
{
prevtempptr=tempptr;
tempptr=tempptr->next;
}
if(tempptr->info == prevtempptr->info)
{
listptr->next=head;
head=listptr;
}
else
{e
listptr->next=prevtempptr->next;
prevtempptr->next=listptr;
}
listptr=prevptr->next;
if (listptr==NULL)
break;
}
prevptr=prevptr->next;
if (prevptr=NULL)
break;
listptr=prevptr->next;
}
return(head);
}
What is wrong with my code and how do I fix it?
The 6th line form last
if (prevptr=NULL)
it should be
if (prevptr==NULL)
Single "=" does the assignment instead of comparison.

can my code for reversing link list be further enhanced

Here is my program which creates a link list and also reverses it.
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *list=NULL;
struct node *root=NULL;
static int count=0;
struct node *create_node(int);//function to create node
void travel_list(void);
void create_list(int);
void reverse_list(void);
int main()
{
int i, j, choice;
printf("Enter a number this will be root of tree\n");
scanf("%d", &i);
create_list(i);
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
while (choice!=0){
printf("Enter a no for link list\n");
scanf("%d",&i);
// printf("going to create list in while\n");
create_list(i);
travel_list();
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
}
printf("reversing list\n");
reverse_list();
travel_list();
}
// end of function main
void create_list (int data)
{
struct node *t1,*t2;
//printf("in function create_list\n");
t1=create_node(data);
t2=list;
if( count!=0)
{
while(t2->next!=NULL)
{
t2=t2->next;
}
t2->next=t1;
count++;
}
else
{
root=t1;
list=t1;
count++;
}
}
struct node *create_node(int data)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
// printf("create node temp->data=%d\n",temp->data);
// printf("the adress of node created %p\n",temp);
return temp;
}
void travel_list(void )
{
struct node *t1;
t1=list;
printf("in travel list\n");
while(t1!=NULL)
{
printf("%d-->",t1->data);
t1=t1->next;
}
printf("\n");
}
void reverse_list(void)
{
struct node *t1,*t2,*t3;
t1=list;
t2=list->next;
t3=list->next->next;
int reverse=0;
if(reverse==0)
{
t1->next=NULL;
t2->next=t1;
t1=t2;
t2=t3;
t3=t3->next;
reverse++;
}
while(t3!=NULL)
{
t2->next=t1;
t1=t2;
t2=t3;
list=t1;
travel_list();
t3=t3->next;
}
t2->next=t1;
list=t2;
}
Above is a fully working code.
I want to know if there can be further enhancement to the above code?
Make your indentation and whitespace usage consistent
Use meaningful identifiers rather than t1, t2 and t3
Make the data member a generic type, for example void * rather than int.
Don't use global variables, pass struct node * pointers to your functions.

Resources