I'm implementing a binary search tree in C.
void add_element(node_t **head, int element) {
if (*head == NULL) {
node_t *new_node = (node_t *) malloc(sizeof(node_t));
if (new_node == NULL) {
printf("Not enough memory\n");
return;
}
new_node->value = element;
new_node->left = NULL;
new_node->right = NULL;
*head = new_node;
} else {
node_t *dummy = *head;
if (dummy->value >= element) {
dummy = dummy->left;
add_element(&dummy, element);
} else {
dummy = dummy->right;
add_element(&dummy, element);
}
}
}
After adding the first element, the tree is not updating as when printing out only the first element appears.
The element is added when calling add_element but seems to not be updated in the original tree.
void log_tree(node_t *head) {
if (head == NULL) {
return;
}
log_tree(head->left);
printf("%d - ", head->value);
log_tree(head->right);
}
void print_menu(node_t *head) {
printf("This is a BST implementation.\n");
log_tree(head);
printf("\n");
printf("1. Add element\n");
printf("2. Remove element\n");
printf("3. Search Element\n");
printf("4. Exit\n");
}
int main() {
node_t *head = NULL;
int run = 1;
int choice, val;
while (run) {
print_menu(head);
printf("Enter your choice: ");
scanf("%d", &choice);
printf("\n");
switch (choice) {
case 1:
printf("Enter new element: ");
scanf("%d", &val);
printf("\n");
add_element(&head, val);
break;
case 2:
printf("Enter element to be removed: ");
scanf("%d", &val);
printf("\n");
remove_element(&head, val);
break;
case 3:
printf("Enter the element you want to search: ");
scanf("%d", &val);
printf("\n");
search_element(head, val);
break;
case 4:
run = 0;
break;
default:
break;
}
}
return 0;
}
This is the node_t:
struct Node {
int value;
struct Node *left;
struct Node *right;
}
typedef struct Node node_t;
I'm new to C and still confused with pointers so maybe I made some mistakes in add_element.
Updated and pasted the full code.
When you do this ...
node_t *dummy = *head;
if (dummy->value >= element) {
dummy = dummy->left;
add_element(&dummy, element);
... the recursive add_element call can modify the value of local variable dummy, but what you want to enable it to modify is (*head)->left. That dummy contains the same value as (*head)->left at that point, which it does, is an entirely different thing from it being the same object.
The same applies in the other branch.
I don't see any reason to involve dummy here. It looks like what you want is:
if ((*head)->value >= element) {
add_element(&(*head)->left, element);
} else {
add_element(&(*head)->right, element);
}
Related
Defination :
Create a “Queue” user-defined structure with the following data members:
A Data
A link to the next node
Perform the following operations on Simple queue using user-defined functions:
Insert an element
Remove an element
Display
Isfull
Isempty
Create a file which stores all values of list.
Code :
#include<stdio.h>
#include<stdlib.h>
struct queue{
int data;
struct queue *next;
};
typedef struct queue node;
node *start=NULL,*rear=NULL;
int choice,i;
void insert();
void rem();
void display();
void isfull();
void isempty();
int main()
{
do
{
printf("\n\t 1.Insert\n\t 2.Remove\n\t 3.Display\n\t 4.isfull\n\t 5.isempty\n\t 6. Exit\n");
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
insert();
break;
}
case 2:
{
rem();
break;
}
case 3:
{
display();
break;
}
case 4:
{
isfull();
break;
}
case 5:
{
isempty();
break;
}
case 6:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{
printf ("\n\t Please Enter a Valid Choice(1/2/3/4/5/6)");
}
}
}
while(choice!=6);
return 0;
}
void insert()
{
node *temp;
temp = (node*)malloc(sizeof(node));
if(temp==NULL){
printf("\n\tQueue is Full\n");
}
else{
printf("Enter a value to be inserted:");
scanf("%d",&i);
temp->data = i;
temp->next=NULL;
if(start==NULL){
start = temp;
rear = temp;
}
else{
rear->next = temp;
rear = temp;
}
}
}
void rem()
{
node *temp;
if(start==NULL)
{
printf("\n\t Queue is Empty \n");
}
else
{
temp = start;
start = start->next;
printf("\n\t The deleted element is %d",temp->data);
free(temp);
}
}
void display()
{
node *temp;
if(start!=NULL)
{
temp = start;
while(temp->next!=NULL){
printf(" %d -> ",temp->data);
temp = temp->next;
}
printf(" %d",temp->data);
}
else
{
printf("\n The Queue is empty");
}
}
void isfull()
{
node *temp;
if (rear == temp - 1)
printf("Queue Overflow \n");
else
printf("Queue is not a Overflow\n");
}
void isempty()
{
node *temp;
if (start == - 1)
printf("Queue is empty \n");
else
printf("Queue is not a empty\n");
}
Looking out for some genuine solution please anyone who can answer this one.
This is because you are comparing an integer value to pointer value you can fix it by replacing -1 to NULL in isempty function it will work perfectly without any warning. There is no need of -1 you need it when you make start and rear variables inside the structure and there data type should be int.
hope it solves your problem
I've been trying to get this search function work but it says element not found even when the element is in the tree. Every other function works.
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *lchild;
int info;
struct node *rchild;
};
int flag;
struct node *root = NULL;
struct node *insert(struct node *ptr, int ikey);
void in_order_search(struct node *ptr, int val);
void display(struct node *ptr,int level);
int main( )
{
struct node *root=NULL,*ptr;
int choice,k,v;
while(1)
{
printf("\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Search\n");
printf("\nEnter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the key to be inserted : ");
scanf("%d",&k);
root = insert(root, k);
break;
case 2:
printf("\n");
display(root,0);
printf("\n");
break;
case 3:
printf("\nEnter the key to be searched : ");
scanf("%d",&v);
in_order_search(root, v);
if (flag==1)
{
printf("Element present in the binary tree\n");
}
else
{
printf("Element not present in the binary tree\n");
}
break;
default:
exit(1);
}
}
return 0;
}
struct node *insert(struct node *ptr, int ikey )
{
if(ptr==NULL)
{
ptr = (struct node *) malloc(sizeof(struct node));
ptr->info = ikey;
ptr->lchild = NULL;
ptr->rchild = NULL;
}
else if(ikey < ptr->info) /*Insertion in left subtree*/
ptr->lchild = insert(ptr->lchild, ikey);
else if(ikey > ptr->info) /*Insertion in right subtree */
ptr->rchild = insert(ptr->rchild, ikey);
else
printf("\nDuplicate key\n");
return ptr;
}
void in_order_search(struct node *ptr, int val)
{
if (!ptr)
{
return;
}
in_order_search(ptr->lchild, val);
if(ptr->lchild == val)
{
printf("\nElement present in the binary tree.\n");
flag = 1;
}
in_order_search(ptr->rchild, val);
}
void display(struct node *ptr,int level)
{
int i;
if(ptr == NULL )
return;
else
{
display(ptr->rchild, level+1);
printf("\n");
for (i=0; i<level; i++)
printf(" ");
printf("%d", ptr->info);
display(ptr->lchild, level+1);
}
}
6 8 7 9 3 4 2
This is the tree I enter and I search for all of the elements in that but it still says element not present in the binary tree. I've been trying to integrate this search function to another code I found on the internet so forgive me if it looks messy. And I'm a beginner as well so if I'm not sure if it's a silly mistake or not.
this is the changes i have made and its works:
void in_order_search(struct node *ptr, int val)
{
if (!ptr)
{
return;
}
in_order_search(ptr->lchild, val);
if(ptr->info == val)
{
/* printf("\nElement present in the binary tree.\n"); to prevent double printing
*/ flag = 1;
return;/* no need to go to the next line*/
}
in_order_search(ptr->rchild, val);
}
also, pay attention to the line caused seg fault:
ptr->lchild == val
this is the bad line
if(ptr->info == val)
this is the correction
I have the following C program that adds Nodes to a tree and then the user can select a sorting method. How can I modify the program in a manner that will allow me to add a LChild and RChild to every node? Any help is highly appreciated since I am completely new to BSTs.
Writiong this because apparently my post is mostly code
Code:
#include <stdio.h>
#include <stdlib.h>
struct treenode {
struct treenode *lchild;
struct treenode *rchild;
int data;
} *root = NULL;
void insertnode(struct treenode **pp,int d)
{
for( ;*pp; )
{
if (d < (*pp)->data) pp = &(*pp)->lchild;
else pp = &(*pp)->rchild;
}
*pp = malloc (sizeof **pp);
(*pp)->data = d;
(*pp)->lchild = NULL;
(*pp)->rchild = NULL;
}
void preorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
printf("%d,",p->data);
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
}
void postorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
printf("%d,",p->data);
}
void inorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
printf("%d,",p->data);
if (p->rchild) preorder(p->rchild);
}
int main(void)
{
root=NULL;
int choice,data;
while(1)
{
printf("\nPress 1 for inserting a node in BST fashion: ");
printf("\nPress 2 for traversing the tree in preorder fashion :");
printf("\nPress 3 for traversing the tree in postorder fashion :");
printf("\nPress 4 for traversing the tree in inorder fashion :");
printf("\nPress 5 to exit :");
printf("\nEnter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1: printf("\nEnter the data to be inserted:");
scanf("%d",&data);
insertnode( &root,data);
break;
case 2: preorder(root);
break;
case 3: postorder(root);
break;
case 4: inorder(root);
break;
case 5: exit(0);
break;
default: printf("\nYou have entered an invalid choice. Please try again");
}
}
return 0;
}
when a new value added to BST,then it check the conditions such that if value ">" the current node value then its we move to the right child of the node and if value "<" then we move to the left child of the node,we do this untill we get to leaf node.
As for your case,just change for condition with while conditions and check if it works.
void insertnode(struct treenode **pp,int d)
{
while((*pp)->data == NULL)
{
if (d < (*pp)->data)
pp = &(*pp)->lchild;
else
pp = &(*pp)->rchild;
}
*pp = malloc (sizeof **pp);
(*pp)->data = d;
(*pp)->lchild = NULL;
(*pp)->rchild = NULL;
}
i've been having trouble trying to implement an input file to my binary search tree and output. I will write my code below, but i dont know where to add the Input file. also in my code i have 4 options, i dont need those. Also i dont know how to use the getopt option, i havent understood that concept yet. and how do i free the memory after the traversal is done to the output file?
# include <stdio.h>
# include <stdlib.h>
typedef struct BST {
int data;
struct BST *lchild, *rchild;
} node;
void insert(node *, node *);
void inorder(node *);
void preorder(node *);
void postorder(node *);
node *search(node *, int, node **);
int main() {
int choice;
char ans = 'N';
int key;
node *new_node, *root, *tmp, *parent;
node *get_node();
root = NULL;
//clrscr();
printf("\nProgram For Binary Search Tree ");
do {
printf("\n1.Create");
printf("\n2.Search");
printf("\n3.Recursive Traversals");
printf("\n4.Exit");
printf("\nEnter your choice :");
scanf("%d", &choice);
switch (choice) {
case 1:
do {
new_node = get_node();
printf("\nEnter The Element ");
scanf("%d", &new_node->data);
if (root == NULL) /* Tree is not Created */
root = new_node;
else
insert(root, new_node);
printf("\nWant To enter More Elements?(y/n)");
// ans = getch();
} while (ans == 'y');
break;
case 2:
printf("\nEnter Element to be searched :");
scanf("%d", &key);
tmp = search(root, key, &parent);
printf("\nParent of node %d is %d", tmp->data, parent->data);
break;
case 3:
if (root == NULL)
printf("Tree Is Not Created");
else {
printf("\nThe Inorder display : ");
inorder(root);
printf("\nThe Preorder display : ");
preorder(root);
printf("\nThe Postorder display : ");
postorder(root);
}
break;
}
} while (choice != 4);
}
/*
Get new Node
*/
node *get_node() {
node *temp;
temp = (node *) malloc(sizeof(node));
temp->lchild = NULL;
temp->rchild = NULL;
return temp;
}
/*
This function is for creating a binary search tree
*/
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);
}
}
/*
This function is for searching the node from
binary Search Tree
*/
node *search(node *root, int key, node **parent) {
node *temp;
temp = root;
while (temp != NULL) {
if (temp->data == key) {
printf("\nThe %d Element is Present", temp->data);
return temp;
}
*parent = temp;
if (temp->data > key)
temp = temp->lchild;
else
temp = temp->rchild;
}
return NULL;
}
/*
This function displays the tree in inorder fashion
*/
void inorder(node *temp) {
if (temp != NULL) {
inorder(temp->lchild);
printf("%d", temp->data);
inorder(temp->rchild);
}
}
/*
This function displays the tree in preorder fashion
*/
void preorder(node *temp) {
if (temp != NULL) {
printf("%d", temp->data);
preorder(temp->lchild);
preorder(temp->rchild);
}
}
/*
This function displays the tree in postorder fashion
*/
void postorder(node *temp) {
if (temp != NULL) {
postorder(temp->lchild);
postorder(temp->rchild);
printf("%d", temp->data);
}
}
I am trying to read in a text file in a linked list and successfully displaying it. But I keep getting the "List is Empty" message which corresponds to (head==NULL) while I can successfully get to read and print in the file once by using the puts(id->...) argument in the read function but I cant get to the display function as I mentioned above.
struct node
{
char name[50];
int id;
struct node *next;
} *head;
int main()
{
int i,num;
struct node *r;
head=NULL;
readfile(*r);
while (1)
{
printf("\nList Operations\n");
printf("============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Delete by ID\n");
printf("4.Delete by Name\n");
printf("5.Exit\n");
printf("Enter your choice: ");
if (scanf("%d", &i) <= 0){
printf("Enter only an integer\n");
exit(0);
} else {
switch(i)
{
case 1:
if(head==NULL)
{
printf("List is Empty\n");
}
else
{
printf("Element in the list are: ");
}
display(r);
break;
case 2:
return 0;
default:
printf("Invalid Choice\n");
}
}
}
void readfile(struct node *r)
{
r=head;
char str[50];
int id;
FILE *ifp=fopen("One.txt","r");
while (fgets(str,50,ifp)!=NULL){
r =(struct node *)malloc(sizeof(struct node));
char *token=strtok(str,",");
strcpy(r->name,token);
puts(r->name);
token=strtok(NULL,"\n");
r->id=token;
puts(r->id);
r->next=NULL;
r=r->next;
}
}
void display(struct node *r)
{
r = head;
if(r == NULL)
{
return;
}
while(r != NULL)
{
printf("Student %s has id %d.\n", r->name,r->id);
r = r->next;
}
printf("\n");
}
In the code you provided you are never assign or allocating anything to head. I guess you need to add code below somewhere
if (head == NULL) {
head = r;
}
or
if (head == NULL) {
head = (struct node *)malloc(sizeof(struct node));
// and initialize it with something
}
Also I recommend you to create more general functions like add_node, like this
void add_node( struct node *r ) {
if(head == NULL) {
head = r;
} else {
struct node* n = head;
while(n->next != NULL) { // go to the end of the list
}
r->next = NULL; // to be sure this will be end of list
n->next = r;
}
}
Then in readfile read data, create new node and pass it to add_node.