C language:Binary search tree with strings - c

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
}

Related

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

BST traversal in C

Traversing a tree using C. It will accept a character and prints the post fix/ in fix/ pre fix.
The problem is when it prints the output it looks like this
input
a
b
c
d
e
f
g
h
i
IN ORDER: C abcdefghi
PRE ORDER: C abcdefghi
POST ORDER: ihgfedcba C
There are spaces and the character 'C' when I traverse and the pre and post order is wrong. I dont know what is wrong. I am wrong in getting the input here? using scanf to get the address of the char?
Here is the whole code
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
typedef struct BST
{
char data;
struct BST *lchild, *rchild;
}node;
node *get_node()
{
node *temp;
temp=(node *)malloc(sizeof(node));
temp->lchild=NULL;
temp->rchild=NULL;
return temp;
}
void insert(node *root, node *new_node)
{
if((new_node->data) < (root->data))
{
if((root->lchild)==NULL)
{
root->lchild=new_node;
}
else
{
insert(root->lchild,new_node);
}
}
if(new_node->data > root->data)
{
if((root->rchild)==NULL)
{
root->rchild=new_node;
}
else
{
insert(root->rchild,new_node);
}
}
}
void inorder(node *temp)
{
if(temp!=NULL)
{
inorder(temp->lchild);
putchar(temp->data);
inorder(temp->rchild);
}
}
void preorder(node *temp)
{
if(temp!=NULL)
{
putchar(temp->data);
preorder(temp->lchild);
preorder(temp->rchild);
}
}
void postorder(node *temp)
{
if(temp!=NULL)
{
postorder(temp->lchild);
postorder(temp->rchild);
putchar(temp->data);
}
}
void main()
{
int i;
node *new_node, *root, *tmp, *parent;
node *get_node();
char c;
clrscr();
for(i=0;i<9;i++)
{
fflush(stdin);
new_node=get_node();
printf("\nenter element: ");
scanf("%c", &new_node->data);
if(root==NULL)
{
root = new_node;
}
else
{
insert(root, new_node);
}
}
printf("\n\nIN ORDER: ");
inorder(root);
printf("\nPRE ORDER: ");
preorder(root);
printf("\nPOST ORDER: ");
postorder(root);
getch();
}
There are spaces and the character 'C' when I traverse
This is most probably due to the missing initialization of root, as Joachim Pileborg noticed.
the pre and post order is wrong
They are not; apart from the spaces and the 'C', you have the degenerate (or pathological) tree
a
\
b
\
c
\
d
\
e
\
f
\
g
\
h
\
i
for which the output orders are correct.

How to find the maximum element from the linked list?

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

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.

Resources