Input file to BST - c

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

Related

Binary Search Tree, tree not updating after adding first node

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

Search function not working in C program to perform functions on a Binary Tree

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

Correct way to delete a node in doubly circular linked list

The purpose of this code is to manage insertion and deletion and visualisation. I just want to know if I'm doing everything correctly, let me know if there are more possible ways to do this. This is my first attempt, i didn't follow any tutorial.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int n;
struct Node *next;
struct Node *prev;
}TNode;
typedef TNode* Node;
void NewNode(Node *pp, int n)
{
Node temp, last;
temp = (Node)malloc(sizeof(struct Node));
temp->n = n;
temp->next = temp;
temp->prev = temp;
if(*pp != NULL)
{
last = (*pp)->prev;
temp->next = (*pp);
temp->prev = last;
last->next = (*pp)->prev = temp;
}
*pp = temp;
}
void ViewList(Node head)
{
if(head == NULL)
{
return;
}
Node node = head->prev;
do
{
printf("Curr: %d\n", node->n);
node = node->prev;
}while(node != head->prev);
}
void ReadData(Node * head, int * n)
{
printf("\nInsert a number:");
scanf("%d", n);
NewNode(head, *n);
}
Node SearchNode(Node head)
{
int d;
printf("\nElement to Delete:");
scanf("%d", &d);
while(head != NULL)
{
if(head->n == d)
{
return head;
}
head = head->next;
}
printf("\nNo Element [%d] Found", d);
return NULL;
}
void Delete(Node * head)
{
Node del = SearchNode(*head);
if(*head == NULL || del == NULL)
{
return;
}
if(*head == del && del->next == *head)
{
*head = NULL;
free(del);
return;
}
if(*head == del)
{
*head = del->next;
del->prev->next = *head;
(*head)->prev = del->prev;
free(del);
return;
}
if((*head)->prev == del)
{
(*head)->prev = del->prev;
del->prev->next = *head;
free(del);
return;
}
del->next->prev = del->prev;
del->prev->next = del->next;
free(del);
}
int Menu()
{
int c;
printf("\n*** M E N U ***\n"
"1 - New Node\n"
"2 - View List\n"
"3 - Delete\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c,n;
Node head = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&head, &n); break;
case 2: ViewList(head); break;
case 3: Delete(&head); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
How can i test if this is a real circular doubly linked list and not a simple doubly linked list?
Your program works fine, the only real bug I detected is in SearchNode: if the element is not present in the list, you enter an infinite loop. Your list is obviously a circular list and therefore you need to check if you have got back to the head in the function, which means that the element you're searching for is not in the list:
Corrected version:
Node SearchNode(Node head)
{
int d;
printf("\nElement to Delete:");
scanf("%d", &d);
Node start = head; // remember where we started
while (head != NULL)
{
if (head->n == d)
{
return head;
}
head = head->next;
if (head == start) // if we are back to where we started
break; // the element hasn't been found and we stop the loop
}
printf("\nNo Element [%d] Found", d);
return NULL;
}
There are also some design flaws, that don't prevent the program from working correctly:
One of them is this: The n variable is not used outside ReadData, so it's pointless to declare it in main and pass it's pointer to ReadData.
Corrected version:
void ReadData(Node * head)
{
int n; // declare n locally
printf("\nInsert a number:");
scanf("%d", &n);
NewNode(head, n);
}
Call it like this: ReadData(&head) and remove int n; from main.

How can I create this linked list with stack in C?

I can create the linked list. But I could not managed to create the stack with it. (Stack cannot be more than 5, and it can be empty as shown in the link). How can I do it? (C language but C++ functions like new int are allowed)
The structure could be something like:
struct linkedStack {
int elements[5];
int top;
struct linkedStack *next;
};
Then manage the stack with top (equals to zero at the beginning)...
Post your code please so we can understand what you are trying to make.
This example can help you
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<stdlib.h>
#include<alloc.h>
void Push(int, node **);
void Display(node **);
int Pop(node **);
int Sempty(node *);
typedef struct stack {
int data;
struct stack *next;
} node;
void main() {
node *top;
int data, item, choice;
char ans, ch;
clrscr();
top = NULL;
printf("\nStack Using Linked List : nn");
do {
printf("\n\n The main menu");
printf("\n1.Push \n2.Pop \n3.Display \n4.Exit");
printf("\n Enter Your Choice");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("\nEnter the data");
scanf("%d", &data);
Push(data, &top);
break;
case 2:
if (Sempty(top))
printf("\nStack underflow!");
else {
item = Pop(&top);
printf("\nThe popped node is%d", item);
}
break;
case 3:
Display(&top);
break;
case 4:
printf("\nDo You want To Quit?(y/n)");
ch = getche();
if (ch == 'y')
exit(0);
else
break;
}
printf("\nDo you want to continue?");
ans = getche();
getch();
clrscr();
} while (ans == 'Y' || ans == 'y');
getch();
}
void Push(int Item, node **top) {
node *New;
node * get_node(int);
New = get_node(Item);
New->next = *top;
*top = New;
}
node * get_node(int item) {
node * temp;
temp = (node *) malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory Cannot be allocated");
temp->data = item;
temp->next = NULL;
return (temp);
}
int Sempty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
int Pop(node **top) {
int item;
node *temp;
item = (*top)->data;
temp = *top;
*top = (*top)->next;
free(temp);
return (item);
}
void Display(node **head) {
node *temp;
temp = *head;
if (Sempty(temp))
printf("\nThe stack is empty!");
else {
while (temp != NULL) {
printf("%d\n", temp->data);
temp = temp->next;
}
}
getch();
}

Reading in and displaying a linked lists via a text file

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.

Resources