This question already has answers here:
What exactly is the value contained in an uninitialized local variable in C?
(2 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 3 months ago.
I have written a code which performs some basic operations on binary search tree. My code runs perfectly on linux ecosystems like Ubuntu or WSL2 but gives incorrect output in windows ecosystem more specifically Windows 10. Here's my code
#include <stdio.h>
#include <malloc.h>
typedef struct TreeNode
{
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
typedef struct node
{
TreeNode *data;
struct node *next;
} node;
typedef struct queue
{
node *head;
node *tail;
int size;
} queue;
TreeNode *insert_in_bst(int element, TreeNode *root);
TreeNode *delete_in_bst(int element, TreeNode *root);
void inorder(TreeNode *root);
void levelwise(TreeNode *root);
void enqueue(queue *q, TreeNode *root);
node *dequeue(queue *q);
void mirror_image(TreeNode *root);
int height(TreeNode *root);
int main(int argc, char *argv[])
{
int n = 0;
printf("Enter elements to be added to bst - ");
scanf("%d", &n);
TreeNode *root;
while (n != -1)
{
root = insert_in_bst(n, root);
scanf("%d", &n);
}
levelwise(root);
printf("\nCurrent inorder - ");
inorder(root);
int del;
printf("\nEnter element to delete - ");
scanf("%d", &del);
delete_in_bst(del, root);
levelwise(root);
printf("\nNew inorder - ");
inorder(root);
printf("\nMirror image\n");
mirror_image(root);
levelwise(root);
int h = height(root);
printf("\nHeight = %d", h);
return 0;
}
TreeNode *insert_in_bst(int element, TreeNode *root)
{
if (!root)
{
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
newNode->data = element;
return newNode;
}
if (element < root->data)
{
root->left = insert_in_bst(element, root->left);
}
else
{
root->right = insert_in_bst(element, root->right);
}
return root;
}
TreeNode *delete_in_bst(int element, TreeNode *root)
{
if (!root)
return NULL;
if (element < root->data)
{
root->left = delete_in_bst(element, root->left);
}
else if (element > root->data)
{
root->right = delete_in_bst(element, root->right);
}
else
{
if (!root->left)
return root->right;
else if (!root->right)
return root->left;
else
{
TreeNode *curr = root->right;
while (!curr->left)
curr = curr->left;
root->data = curr->data;
root->right = delete_in_bst(curr->data, root->right);
}
}
return root;
}
void inorder(TreeNode *root)
{
if (!root)
return;
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
void levelwise(TreeNode *root)
{
node *currNode = (node *)malloc(sizeof(node));
currNode->data = root;
queue *q = (queue *)malloc(sizeof(queue));
enqueue(q, root);
while (q->size != 0)
{
int l = q->size;
for (int i = 0; i < l; i++)
{
node *temp = dequeue(q);
TreeNode *t = temp->data;
printf("%d ", t->data);
if (t->left)
{
enqueue(q, t->left);
}
if (t->right)
{
enqueue(q, t->right);
}
}
printf("\n");
}
}
void enqueue(queue *q, TreeNode *root)
{
node *temp = (node *)malloc(sizeof(node));
temp->data = root;
if (!q || !q->head)
{
q->head = temp;
q->tail = temp;
q->size = 1;
}
else
{
q->tail->next = temp;
q->tail = q->tail->next;
q->size++;
}
}
node *dequeue(queue *q)
{
node *top = q->head;
q->head = q->head->next;
q->size--;
return top;
}
void mirror_image(TreeNode *root)
{
if (!root)
return;
TreeNode *temp = root->left;
root->left = root->right;
root->right = temp;
mirror_image(root->left);
mirror_image(root->right);
}
int height(TreeNode *root)
{
if (!root)
return 0;
int lh = height(root->left);
int rh = height(root->right);
return 1 + (lh > rh ? lh : rh);
}
Heres the output on Windows ecosystems
Here's the output on linux/wsl2
On further debugging on Windows systems, i found out that by default; value to root is assigned as 1. On linux systems this thing doesnt happen. Can someoe help me find out the reason?
Thank you!
Below is the menu driven program for various operation in BST. The major problem I am getting is when I free function runs in delete function please help and update the given program. Whenever I try to delete any node after insertion, the program abruptly ends. I tried to debug but the problem still persists.
#include <stdio.h>
#include <stdlib.h>
struct btNode
{
int data;
struct btNode *right;
struct btNode *left;
};
int found;
struct btNode *temp2;
struct btNode *create(int);
struct btNode *insert(struct btNode *, int);
void inorder(struct btNode *);
void preorder(struct btNode *);
void postorder(struct btNode *);
void delete (struct btNode *, int);
int main()
{
int choice, item;
struct btNode *root = NULL;
do
{
printf("\nChoose one of the options:\n");
printf("1. Insert 2. Delete 3. Inorder 4. Postorder 5. Preorder 6. Exit\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("\nEnter any number to insert:");
scanf("%d", &item);
root = insert(root, item);
break;
case 2:
printf("\nEnter any number to delete:");
scanf("%d", &item);
delete(root, item);
break;
case 3:
inorder(root);
break;
case 4:
postorder(root);
break;
case 5:
preorder(root);
break;
case 6:
break;
default:
printf("\nWRONG INPUT");
}
} while (choice != 6);
return 0;
}
struct btNode *create(int num)
{
struct btNode *temp1 = (struct btNode *)malloc(sizeof(struct btNode));
temp1->data = num;
temp1->left = NULL;
temp1->right = NULL;
return temp1;
}
struct btNode *search(struct btNode *root, int num)
{
struct btNode *temp1 = root;
while (temp1 != NULL)
{
if (temp1->data == num)
{
found = 1;
return temp1;
}
else
{
if (temp1->data >= num)
{
temp2 = temp1;
temp1 = temp1->left;
}
else
{
temp2 = temp1;
temp1 = temp1->right;
}
}
}
found = 0;
}
struct btNode *insert(struct btNode *root, int num)
{
struct btNode *temp1 = create(num);
if (root == NULL)
{
root = temp1;
printf("%d inserted\n", root->data);
}
else
{
temp2 = root;
while (temp2 != NULL)
{
if (temp2->data >= num)
{
if (temp2->left)
{
temp2 = temp2->left;
}
else
{
temp2->left = temp1;
printf("%d inserted\n", temp2->left->data);
break;
}
}
else
{
if (temp2->right)
{
temp2 = temp2->right;
}
else
{
temp2->right = temp1;
printf("%d inserted\n", temp2->right->data);
break;
}
}
}
}
return root;
}
void delete (struct btNode *root, int num)
{
struct btNode *temp1 = search(root, num);
if (found == 0)
{
printf("element not found");
return;
}
else
{
if (temp1->left == NULL && temp1->right == NULL)
{
free(temp1);
}
if (temp1->left != NULL && temp1->right == NULL)
{
if (temp2->left = temp1)
{
temp2->left = temp1->left;
free(temp1);
}
if (temp2->right = temp1)
{
temp2->right = temp1->left;
free(temp1);
}
}
if (temp1->left == NULL && temp1->right != NULL)
{
if (temp2->left = temp1)
{
temp2->left = temp1->right;
free(temp1);
}
if (temp2->right = temp1)
{
temp2->right = temp1->right;
free(temp1);
}
}
if (temp1->left != NULL && temp1->right != NULL)
{
struct btNode *node1 = temp1;
struct btNode *node2 = temp1->right;
while (node2->left != NULL)
{
node1 = node2;
node2 = node2->left;
}
temp1->data = node2->data;
temp1 = node2;
free(temp1);
}
}
}
void inorder(struct btNode *r)
{
if (r == NULL)
{
printf("Tree is empty");
return;
}
else
{
if (r->left)
inorder(r->left);
printf("%d ", r->data);
if (r->right)
inorder(r->right);
}
}
void preorder(struct btNode *r)
{
if (r == NULL)
{
printf("Tree is empty");
return;
}
else
{
printf("%d ", r->data);
if (r->left)
preorder(r->left);
if (r->right)
preorder(r->right);
}
}
void postorder(struct btNode *r)
{
if (r == NULL)
{
printf("Tree is empty");
return;
}
else
{
if (r->left)
postorder(r->left);
if (r->right)
postorder(r->right);
printf("%d ", r->data);
}
}
Your delete() function has errors at several levels. Among these:
general API: deletion can change the tree's root node, but you make no provision for that. At minimum deletion changes the root node when the only node of a one-node tree is deleted, but with an approach such as yours, the root node will change whenever you delete the value that it contains.
Implementation flaw: in a similar vein, when you perform a search and discover the target value in the root node, you do not set the (very poorly named) temp2 file-scope variable. When that search is performed in the context of a deletion, it may result in either delete() attempting to dereference a null pointer, or in it corrupting the tree by modifying a random node as if it were the parent on the target node.
Implementation flaw: when you delete a leaf node (other than the root), you need to set its parent's pointer to it to NULL.
Bad code: you have several if statements in delete() that use = where they mean ==.
Poor style: do not rely on global variables (temp2, found). Where you want your functions to return multiple values then either use structures or endow the functions with out parameters.
What's wrong in my code? I successfully created a tree and everything is working fine except printInorder function and print statement in void main. When I try to print with %s its skipping the entire line.
Can you please help me in resolving this? I even tried fflush but it doesn't help me in my case and I don't try any scanf statement in my code.
struct Tree
{
char data[10];
struct Tree *left;
struct Tree *right;
} * root;
struct Tree *createNode(char data[])
{
struct Tree *node = malloc(sizeof(struct Tree));
strcpy(node->data, data);
node->left = node->right = NULL;
insertTree(node, root, data);
}
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
}
}
else
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->right == NULL)
{
temp->right = currentNode;
printf("data inserted successfully at right");
}
else
{
insertTree(currentNode, temp->right,data);
}
}
}
void printInorder(struct Tree *tmp)
{
if (tmp == NULL)
return;
printInorder(tmp->left);
printf("%s ",tmp->data);
printInorder(tmp->right);
}
void main()
{
struct Tree *root = createNode("saish");
struct Tree *d1 = createNode("ansha");
struct Tree *d2 = createNode("shish");
printf("%s",root->data);
printInorder(root);
}
createNode function doesn't return anything even though it is defined to do so.
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
return node;
}
}
#include <stdio.h>
#include <stdlib.h>
typedef struct node_st {
int data;
struct node_st* left;
struct node_st* right;
};
void preorder(struct node_st *root) {
if (root != NULL) {
printf("%d\n", root->data);
preorder(root->left);
preorder(root->right);
}
}
void postorder(struct node_st *root) {
if (root != NULL) {
postorder(root->left);
postorder(root->right);
printf("%d\n", root->data);
}
}
struct node_st* createNode(value) {
struct node_st* newNode = malloc(sizeof(struct node_st));
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
struct node_st* insertLeft(struct node_st* root, int value){
root->left = createNode(value);
return root->left;
}
struct node_st* insertRight(struct node_st* root, int value){
root->right = createNode(value);
return root->right;
}
int main() {
struct node_st* root = createNode(2);
insertLeft(root, 6);
insertRight(root, 9);
insertLeft(root->left, 2);
insertLeft(root->right, 1);
printf("\nPreorder\n");
preorder(root);
printf("\nPostorder\n");
postorder(root);
}
I need to make a function to store a tree into a string with bracket representation like (A(B)(C)) and to read it to make a tree, but I'm having trouble finding info online on how to do this in C, would appreciate any help.
The next step after this is to store it and read it from a file, but I can handle that with the documentation.
Here is code that prints the tree in bracketed representation. The format you request is ambiguous — if a node has only one child, you cannot tell whether that child is the left child or the right child. That ambiguous format is produced by the functions with _v1_ in the name: print_v1_tree(), print_v1_preorder(), print_v1_postorder(), print_v1_inorder().
There is an alternative format where an empty subtree is represented by () unless the node is a leaf node (both child nodes are null).
There's also a free_tree() function to release the memory for a tree.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_st
{
int data;
struct node_st *left;
struct node_st *right;
} Node;
typedef void (*Print)(const Node *node);
extern struct node_st *createNode(int value);
extern struct node_st *insertLeft(struct node_st *root, int value);
extern struct node_st *insertRight(struct node_st *root, int value);
extern void postorder(struct node_st *root);
extern void preorder(struct node_st *root);
extern void inorder(struct node_st *root);
extern void print_v1_postorder(const Node *node);
extern void print_v1_inorder(const Node *node);
extern void print_v1_preorder(const Node *node);
extern void print_v1_tree(const char *tag, const Node *node, Print print);
extern void print_v2_postorder(const Node *node);
extern void print_v2_inorder(const Node *node);
extern void print_v2_preorder(const Node *node);
extern void print_v2_tree(const char *tag, const Node *node, Print print);
extern void free_tree(Node *node);
void preorder(struct node_st *root)
{
if (root != NULL)
{
printf("%d\n", root->data);
preorder(root->left);
preorder(root->right);
}
}
void postorder(struct node_st *root)
{
if (root != NULL)
{
postorder(root->left);
postorder(root->right);
printf("%d\n", root->data);
}
}
void inorder(struct node_st *root)
{
if (root != NULL)
{
inorder(root->left);
printf("%d\n", root->data);
inorder(root->right);
}
}
struct node_st *createNode(int value)
{
struct node_st *newNode = malloc(sizeof(struct node_st));
if (newNode == NULL)
{
fprintf(stderr, "Failed to allocate memory for a node\n");
exit(1);
}
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
struct node_st *insertLeft(struct node_st *root, int value)
{
root->left = createNode(value);
return root->left;
}
struct node_st *insertRight(struct node_st *root, int value)
{
root->right = createNode(value);
return root->right;
}
void print_v1_preorder(const Node *node)
{
printf("%d", node->data);
if (node->left != NULL)
{
putchar('(');
print_v1_preorder(node->left);
putchar(')');
}
if (node->right != NULL)
{
putchar('(');
print_v1_preorder(node->right);
putchar(')');
}
}
void print_v1_inorder(const Node *node)
{
if (node->left != NULL)
{
putchar('(');
print_v1_inorder(node->left);
putchar(')');
}
printf("%d", node->data);
if (node->right != NULL)
{
putchar('(');
print_v1_inorder(node->right);
putchar(')');
}
}
void print_v1_postorder(const Node *node)
{
if (node->left != NULL)
{
putchar('(');
print_v1_postorder(node->left);
putchar(')');
}
if (node->right != NULL)
{
putchar('(');
print_v1_postorder(node->right);
putchar(')');
}
printf("%d", node->data);
}
void print_v1_tree(const char *tag, const Node *node, Print print)
{
printf("%s: (", tag);
if (node != NULL)
(*print)(node);
putchar(')');
putchar('\n');
}
void print_v2_preorder(const Node *node)
{
if (node == NULL)
return;
printf("%d", node->data);
if (node->left != NULL || node->right != NULL)
{
putchar('(');
print_v2_preorder(node->left);
putchar(')');
}
if (node->right != NULL || node->left != NULL)
{
putchar('(');
print_v2_preorder(node->right);
putchar(')');
}
}
void print_v2_inorder(const Node *node)
{
if (node == NULL)
return;
if (node->left != NULL || node->right != NULL)
{
putchar('(');
print_v2_inorder(node->left);
putchar(')');
}
printf("%d", node->data);
if (node->right != NULL || node->left != NULL)
{
putchar('(');
print_v2_inorder(node->right);
putchar(')');
}
}
void print_v2_postorder(const Node *node)
{
if (node == NULL)
return;
if (node->left != NULL || node->right != NULL)
{
putchar('(');
print_v2_postorder(node->left);
putchar(')');
}
if (node->right != NULL || node->left != NULL)
{
putchar('(');
print_v2_postorder(node->right);
putchar(')');
}
printf("%d", node->data);
}
void print_v2_tree(const char *tag, const Node *node, Print print)
{
printf("%s: (", tag);
if (node != NULL)
(*print)(node);
putchar(')');
putchar('\n');
}
/* Must be post-order release, but could do right before left */
void free_tree(Node *node)
{
if (node != NULL)
{
free(node->left);
free(node->right);
free(node);
}
}
int main(void)
{
struct node_st *root = createNode(3);
insertLeft(root, 6);
insertRight(root, 9);
insertLeft(root->left, 2);
insertLeft(root->right, 1);
printf("\nPreorder\n");
preorder(root);
printf("\nPostorder\n");
postorder(root);
printf("\nInorder\n");
inorder(root);
printf("\nAmbiguous:\n");
print_v1_tree("Preorder", root, print_v1_preorder);
print_v1_tree("Inorder", root, print_v1_inorder);
print_v1_tree("Postorder", root, print_v1_postorder);
print_v1_tree("Empty", NULL, print_v1_inorder);
printf("\nUnambiguous:\n");
print_v2_tree("Preorder", root, print_v2_preorder);
print_v2_tree("Inorder", root, print_v2_inorder);
print_v2_tree("Postorder", root, print_v2_postorder);
print_v2_tree("Empty", NULL, print_v2_inorder);
insertRight(root->right, 13);
insertRight(root->left, 3);
insertRight(root->left->right, 4);
insertRight(root->left->right->right, 5);
printf("\nExtended tree - unambiguous:\n");
print_v2_tree("Preorder", root, print_v2_preorder);
print_v2_tree("Inorder", root, print_v2_inorder);
print_v2_tree("Postorder", root, print_v2_postorder);
print_v2_tree("Empty", NULL, print_v2_inorder);
free_tree(root);
return 0;
}
The output from this is:
Preorder
3
6
2
9
1
Postorder
2
6
1
9
3
Inorder
2
6
3
1
9
Ambiguous:
Preorder: (3(6(2))(9(1)))
Inorder: (((2)6)3((1)9))
Postorder: (((2)6)((1)9)3)
Empty: ()
Unambiguous:
Preorder: (3(6(2)())(9(1)()))
Inorder: (((2)6())3((1)9()))
Postorder: (((2)()6)((1)()9)3)
Empty: ()
Extended tree - unambiguous:
Preorder: (3(6(2)(3()(4()(5))))(9(1)(13)))
Inorder: (((2)6(()3(()4(5))))3((1)9(13)))
Postorder: (((2)(()(()(5)4)3)6)((1)(13)9)3)
Empty: ()
Converting this to store the data in a string is not too difficult. Parsing it is fiddlier — regardless of which format you use. Preorder may be the easiest to handle.
Here is my code for storing a tree in a string, using sprintf (return number of chars stored), given:
A node to begin storing (root on first call)
A pre alocated string, you can modify the code to realloc
The position on the string you are printing (i)
The max size of the string
int string_parenthesis_by_node(node_t *nd, char *str, int i, int max){
if (!nd) return 0;
// checks the size limit
int added = (ceil(log10(nd->key > 0 ? nd->key : 1)) + 2);
if (i + added >= max){
fprintf(stderr, "TOO LARGE INPUT TO BUFFER, tried to add %d on top of %d, maxing %d", added, i, max);
return 0;
}
// res is the current position you are storing
// it is incremented after every sprint
int res = i;
res += sprintf(str+res, "(%d", nd->key);
res += string_parenthesis_by_node(nd->left, str, res, max);
res += string_parenthesis_by_node(nd->right, str, res, max);
res += sprintf(str+res, ")");
return res-i;
}```
this program creates a sorted list and then inserts an element such that the list still remains sorted. I think the logic is ok..but the program doesn't print the new list formed.Here is the code. what is wrong?
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct list {
int number;
struct list *next;
};
typedef struct list node;
void create(node *);
void print(node *);
void sortedInsert(node **);
main() {
int user_response;
node *head;
head = (node *)malloc(sizeof(node));
create(head);
printf("Look at your creation!! A linked list!!1 heheheh...........\n");
print(head);
printf("Do you want to experience some \"sort\" of thrill?\n1 for yes..\n");
scanf("%d",&user_response);
if(user_response == 1) {
sortedInsert(&head);
printf("Look at the marvel of linked list...\n");
print(head);
}
else {
printf("Ha\n tired fellow,lack of ambition!!!\n");
exit(0);
}
return 0;
}
void create(node *head) {
printf("Enter a number,-999 to stop\n");
scanf("%d",&head->number);
if(head->number == -999) {
head->next = NULL;
}
else {
head->next = (node *)malloc(sizeof(node));
create(head->next);
}
}
void print(node *head) {
if(head->next != NULL) {
printf("%d-->",head->number);
print(head->next);
}
else {
printf("%d",head->number);
}
}
void sortedInsert(node **headRef) {
node *new_node;
node *prev_ptr = *headRef;
node *dummy_ptr = *headRef;
int key;
printf("Which value do you wanna insert\n");
scanf("%d",&key);
new_node = (node *)malloc(sizeof(node));
new_node->number = key;
while((*headRef)->next != NULL) {
if((*headRef)->number >= key) {
prev_ptr->next = new_node;
new_node->next = *headRef;
*headRef = dummy_ptr;
}
else {
prev_ptr = *headRef;
*headRef = (*headRef)->next;
}
}