Debug Binary Search Tree in C - c

I was trying to create a BST in C. I was just adding bare basic functionalities. However, I have seemed to run into a problem either adding a node or with the in-order traversal - somehow created an infinite loop. Please offer feedback as I am trying to improve. Thanks!
#include <stdio.h>
#include <stdlib.h>
//node structure
struct node{
int data;
struct node* left;
struct node* right;
}typedef node;
//create node
node * createLeaf(int x){
node * temp = (node*)malloc(sizeof(node));
temp->data = x;
temp->left = NULL;
temp->right = NULL;
return temp;
}
//insert node
node *insert(node *root,int x){
if(root == NULL){
root = createLeaf(x);
return root;
}
else{
if(x > root->data){
root->right = insert(root->right,x);
}
else if(x < root->data){
root->left = insert(root->left,x);
}
}
return root;
}
//in-order traversal
void inorder(node * root){
while(root!=NULL){
inorder(root->left);
printf("%d\n",root->data);
inorder(root->right);
}
}
int main()
{
node * root = NULL;
root = insert(root,5);
insert(root,8);
insert(root,1);
inorder(root);
printf("Hello World");
return 0;
}

What #Eugene suggested replacing while with if will fix the problem
Or you can add a break at the end of while loop and it should also solve your problem.
But I will suggest to only use either recursion or iteration.

Related

Why try to print the value in the left node and right node of the binary search tree causing a Segmentation fault?

I am trying to implement the insert operation of a binary search tree using C. Why does the following code show a Segmentation fault when trying to print the value of the left and right nodes of the root?
Please explain what caused this error exactly.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
};
struct node *root, *temp = NULL;
void insert(int data) {
struct node *newNode = (struct node*) malloc(sizeof(struct node));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
if (root == NULL){
// if tree is empty insert the node as root
root = newNode;
}else {
// if the tree is not empty
temp = root;
while(temp != NULL) {
if(data <= root->data) {
temp = temp->left;
}
if(data > root->data) {
temp = temp->right;
}
}
temp = newNode;
}
}
int main() {
insert(7);
insert(4);
insert(8);
printf("\n\n------%d------", root->left->data);
printf("\n\n------%d------", root->right->data);
return 0;
}
The assignment temp = newNode only stores a pointer in the temp variable, not somewhere in the tree. So your tree's root node will never get any child. By consequence the main program is dereferencing a root->left pointer that is NULL, and this explains the error you get.
In order to really attach the new node at the right place in the tree, you need to modify a left or right member of some node. You can do this in several ways. One is to make temp a pointer-pointer, so that it will have the address of a left or right member. Then the assignment to *temp, will be an assignment to a node's left or right member, effectively extending the tree with that new node.
Here is the updated part of the code:
struct node **temp = &root;
while(*temp != NULL) {
if(data <= root->data) {
temp = &(*temp)->left;
}
if(data > root->data) {
temp = &(*temp)->right;
}
}
*temp = newNode;
okay you have a few issues here,
first of all, temp will point back to newNode, as you have not copied newNode's values to where temp is pointing now.
second and no less important, newNode is created within the scope of insert() - therefore, root will always remain null, as root points after execution of insert() to data wich no longer exists.
I have improved your code, and this definitely works as expected
hope it has helped.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node* left;
struct node* right;
}node;
node *root=NULL;
void insert(int data) {
node *temp = NULL;
if (root == NULL){
/* if tree is empty insert the node as root*/
root = malloc(sizeof(struct node));
root->data=data;
}else {
/*if the tree is not empty*/
temp = root;
while(temp->left!= NULL||temp->right!=NULL) {
if(data <= temp->data){
if(temp->left==NULL)
break;
else
temp = temp->left;
}
else if(data > temp->data){
if(temp->right==NULL)
break;
else
temp = temp->right;
}
}
if(data<= temp->data){
temp->left=malloc(sizeof(struct node));
(temp->left)->data=data;
}
else {
temp->right=malloc(sizeof(struct node));
(temp->right)->data=data;
}
/*temp=newNode;*/
}
}
int main() {
insert(7);
insert(4);
insert(8);
printf("\n\n------%d------", root->left->data);
printf("\n\n------%d------", root->right->data);
return 0;
}

I am using struct in Turbo C++ — it is giving error declaration is not Allowed Here [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Error in Turbo C++:
I compile this file in Turbo C++ but it takes many errors type of struct declaration is not allowed.
Here is the code:
#include<stdio.h>
#include<malloc.h>
struct node{
int data;
struct node* left;
struct node* right;
};
struct node* createNode(int data){
struct node *n; // creating a node pointer
n = (struct node *) malloc(sizeof(struct node)); //
n->data = data;
n->left = NULL;
n->right = NULL;
return n;
}
void inOrder(struct node* root){
if(root!=NULL)
{
inOrder(root->left);
printf("%d ", root->data);
inOrder(root->right);
}
}
struct node * search(struct node* root, int key){
if(root==NULL)
{
return NULL;
}
if(key==root->data)
{
return root;
}
else if(key<root->data)
{
return search(root->left, key);
}
else{
return search(root->right, key);
}
}
void insert(struct node *root, int key){
struct node *prev = NULL;
while(root!=NULL){
prev = root;
if(key==root->data){
printf("Cannot insert %d, already in BST", key);
return;
}
else if(key<root->data){
root = root->left;
}
else{
root = root->right;
}
}
struct node* new = createNode(key);
if(key<prev->data){
prev->left = new;
}
else{
prev->right = new;
}
}
struct node *inOrderPredecessor(struct node *root){
root = root->left;
while (root->right!=NULL)
{
root = root->right;
}
return root;
}
struct node *deleteNode(struct node *root, int value)
{
struct node* iPre;
if (root == NULL){
return NULL;
}
if (root->left==NULL&&root->right==NULL)
{
free(root);
return NULL;
}
if (value < root->data){
root-> left = deleteNode(root->left,value);
}
else if (value > root->data){
root-> right = deleteNode(root->right,value);
}
//deletion strategy when the node is found
else{
iPre = inOrderPredecessor(root);
root->data = iPre->data;
root->left = deleteNode(root->left, iPre->data);
}
return root;
}
int main(){
struct node *p = createNode(8);
insert(p,3);
insert(p,1);
insert(p,6);
insert(p,7);
insert(p,10);
insert(p,14);
insert(p,4);
inOrder(p);
printf("\n After Deleting NOde\n");
deleteNode(p,4);
inOrder(p);
struct node* n = search(p, 6);
if(n!=NULL){
printf("\nFound Element : %d", n->data);
}
else{
printf("Element not found");
}
return 0;
}
This code runs smoothly in VSCODE but I want to run in Turbo C++.
How can I fix it?
I am a beginner in data structures. A struct is a type consisting of a sequence of members whose storage is allocated in an ordered sequence (as opposed to union, which is a type consisting of a sequence of members whose storage overlaps)
Turbo C++ is extremely obsolete compiler. It supports very old C. It requires all variable declarations to be placed in the first lines after opening braces. For example
struct node* new = createNode(key);
Should be split
struct node* new = NULL; // goes up to struct node* next = NULL;
...
new = createNode(key); // initialization in a desired line
void insert(struct node *root, int key){
struct node *prev = NULL;
struct node* new = NULL; // <--
while(root!=NULL){
prev = root;
if(key==root->data){
printf("Cannot insert %d, already in BST", key);
return;
}
else if(key<root->data){
root = root->left;
}
else{
root = root->right;
}
}
new = createNode(key); // <--
if(key<prev->data){
prev->left = new;
}
else{
prev->right = new;
}
}
Split similarly all late declarations with initializations to early declarations and late initializations.

i tried insertion in BST tree using itteration but the output is incomplete. Where is might be the problem?

**I was doing insertion operation in BST using itteraton mechanism. I did inorder traversal using recursion for swift display of my tree and to know whether i am doing it right or wrong. However, the output is always 4 . I donot understand ummwhat might be the problem. Is my root not updating? **
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int data;
struct Node *left;
struct Node *right;
}node;
node *new(int data){ //create node
node *pw;
pw = (node *)malloc(sizeof(node *));
pw->data = data;
pw->left = NULL;
pw->right= NULL;
return pw;
}
node *insert(node *root, int data ){ //insert using itteration
node *pr;
pr = root;
if(root==NULL)
return new(data);
while(pr!= NULL){
if(data< pr->data){
if(pr->left==NULL){
pr->data = data;
pr=NULL;
}
else{
pr= pr->left;
}
}else if(data> pr->data){
if(pr->right==NULL){
pr->data = data;
pr=NULL;
}
else{
pr= pr->right;
}
}
}
return pr;
}
void inorder(node *root) {
if (root != NULL) {
// Traverse left
inorder(root->left);
// Traverse root
printf("%d -> ", root->data);
// Traverse right
inorder(root->right);
}
}
void main(){
node* root = NULL;
root = insert(root,5);
root = insert(root,6);
root = insert(root,4);
inorder(root); //inorder traversal for displaying tree
}
it seems like you are always changing the parent node's data instead of creating a new node to be the child of the parent node.
so instead of:
if(pr->left==NULL){
pr->data = data;
pr=NULL;
}
it needs to be:
if(pr->left==NULL){
pr->left = new(data);
break; /*you have inserted the node, a break will stop the loop*/
}
same change should be applied for the right if statement.
And further - insert has this return statement: return pr and that you save into root in the caller. However, root is only to be changed when root is NULL to start with. In other words: Returning pr is wrong.
Therefore do this change:
return pr; ---> return root;

Correctly Implementing a Linked List in C

I am trying to implement a linked list from scratch in C:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * next;
};
void insert(struct node** root, int data){
// Create a Node
struct node * temp = malloc(sizeof(struct node));
temp->data = data;
temp->next = NULL;
// Either root is NULL or not
if (*root == NULL){
*root = temp; // Directly modify the root
}
else {
struct node * t = *root;
while (t->next!=NULL){
t = t->next;
}
t->next = temp; // Append at the last
}
}
void printList(struct node * root){
while(root!=NULL){
printf("%d\t", root->data);
}
}
struct node * search(struct node* root, int key){
while (root!=NULL) {
if (root->data == key) return root;
}
return NULL;
}
int main(){
struct node * head = NULL;
insert(&head,0);
insert(&head,1);
insert(&head,2);
insert(&head,3);
insert(&head,4);
printList(head);
}
Now, when I run the program, my output is:
0 0 0 0 0 0 0 0 0 0
However, my list doesn't contain all zeroes or 10 elements.
My logic seems correct but somehow code has a bug.
On a side note, is there a way to avoid double pointers, can't I work with only pointers while inserting in a linked list?
There is a small bug in the printList() function.
In printList() function, root not updated, to iterate whole list you should do root = root->next
void printList(struct node * root){
while(root!=NULL){
printf("%d\t", root->data);
root = root->next; /* you miss this one */
}
}
Same mistake is repeated in search() function also,
struct node * search(struct node* root, int key){
while (root!=NULL) {
if (root->data == key)
return root;
else
root = root->next; /* if key not found root should be updated to next one */
}
return NULL;
}

sum even numbers in BST

In this code, I need create a function which will sum even numbers in my BST. I don't know how to pass all nodes of my tree. Here is the code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int key;
struct node *left, *right;
};
struct node *newNode(int item) {
struct node *temp=(struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
struct node* insert(struct node* node, int key) {
if (node == NULL) return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
return node;
}
void main(void)
{
struct node *root = NULL;
int data[]={3,1,2,6,4,7,8}, n, i;
n=sizeof(data)/sizeof(data[0]);
for(i=0;i<n;i++)
root=insert(root,data[i]);
}
Try something like this. Sorry, have no C-compiler at hand.
int sum(struct node *root) {
if (root == NULL) {
return 0;
}
int value = 0;
if (root->key % 2 == 0) {
value = root->key;
}
return value + sum(root->left) + sum(root->right);
}
You need to do one of the different search, BFS or DFS, for search in every node of the tree. Also in every moment you should save the actual sum of even numbers. The comparison should be like
if(node->key % 2 == 0){
final += node->key;
}
Hope this help.

Resources