Converting a Binary tree to a Binary Search Tree - c

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

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
}

implementing shell sort for linked lists?

I'm trying to implement shell sort on singly-linked lists. What I have tried to do is get the respective elements based on the inc value and sort them. However, I'm only familiar with shell sort implementation on arrays and not linked lists. Any help is appreciated.
struct node
{ int data;
struct node *next;
};
typedef struct node n;
void add(int a);
void shellsort(int size);
void display();
void moveptr(n*a, int distance);
n* head=NULL;
void main()
{ int i,x,size;
printf("How many elements do you want to enter: ");
scanf("%d",&size);
printf("Enter the data: ");
for(i=0;i<size;i++)
{ scanf("%d",&x);
add(x);
}
printf("List currently is: ");
display();
shellsort(size);
printf("\nafter sorting list is: ");
display();
}
void add(int a)
{ n *temp = (n*)malloc(sizeof(n));
temp->data=a;
temp->next=head;
head=temp;
}
void display()
{ n* temp=head;
while(temp!=NULL)
{ printf("%d-->",temp->data);
temp=temp->next;
}
}
void moveptr(n *ptr, int distance) // this moves a temp pointer to required location
{ int i=0;
while(i<distance)
{
ptr=ptr->next;
i=i+1;
}
}
void shellsort(int size)
{ int i,j,temp,inc=size/2;
n *a=head,*b=head;
do{
for(i=0;i<size;i++)
{
for(j=i+inc;j<size;j+=inc)
{ b=head;
moveptr(b,j);
if(a->data > b->data)
{ temp=b->data;
b->data=a->data;
a->data=temp;
}
}
a=a->next;
}
inc=inc/2;
}while(inc>=1);
}
If you insist on using shell sort:
allocate an array of pointers to list items,
initialize this array to point to the individual items in the list
sort the array using shell sort
relink the list in the order of the array elements
free the list.

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.

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

Depth first search using adjacency list

I m trying to unterstand the code below but thereĀ“s something not clear in DFS function
enter code here
#include<stdio.h>
typedef struct node
{
struct node *next;
int vertex;
}node;
node *G[20];
int visited[20];
int n;
void read_graph();
void insert(int,int);
void DFS(int);
void main()
{
int i;
read_graph();
//initialised visited to 0
for(i=0;i<n;i++)
visited[i]=0;
DFS(0);
}
void DFS(int i)
{
node *p;
printf("\n%d",i);
p=G[i];
visited[i]=1;
while(p!=NULL)
{
i=p->vertex;
if(!visited[i])
DFS(i);
p=p->next;
}
}
void read_graph()
{
int i,vi,vj,no_of_edges;
printf("Enter number of vertices:");
scanf("%d",&n);
//initialise G[] with a null
for(i=0;i<n;i++)
{
G[i]=NULL;
//read edges and insert them in G[]
printf("Enter number of edges:");
scanf("%d",&no_of_edges);
for(i=0;i<no_of_edges;i++)
{
printf("Enter an edge(u,v):");
scanf("%d%d",&vi,&vj);
insert(vi,vj);
}
}
}
void insert(int vi,int vj)
{
node *p,*q;
//acquire memory for the new node
q=(node*)malloc(sizeof(node));
q->vertex=vj;
q->next=NULL;
//insert the node in the linked list number vi
if(G[vi]==NULL)
G[vi]=q;
else
{
//go to end of the linked list
p=G[vi];
while(p->next!=NULL)
p=p->next;
p->next=q;
}
}
how does the backtracking happen after terminating the while loop in the function DFS() ? i donĀ“t get it
Thx
Well, this is not a DFS (Depth First Search), as nothing is searched for. All that your DFS function does is traverse all edges, marking their nodes as visited. Once done, you only know if this is a connected graph - if there are any edges that have not been visited, then they have not been marked, and so cannot be reached from G[0].
the original code is not mine .. i just found it on this website : http://www.thecrazyprogrammer.com/2014/03/depth-first-search-dfs-traversal-of-a-graph.html

Resources