I'm sure I'm making some silly mistake, hope somebody can help me out and clear some of my basic concepts.
Here's my code to create and print a basic BST in C:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct bst
{
int value;
struct bst *left;
struct bst *right;
}T;
T *temp=NULL, *newnode;
T *tree; // had globally declared as NULL previously
T* createnode(int val)
{
newnode=(T*)malloc(sizeof(T));
if(newnode==NULL)
{
printf("Memory not allocated! \n");
}
else
{
newnode->value=val;
newnode->right=NULL;
newnode->left=NULL;
}
return newnode;
}
T * insert_tree(T *tree, int val)
{
if(tree==NULL)
{
newnode=createnode(val);
tree=newnode;
return tree;
}
if (val < tree->value)
{
tree->left=insert_tree(tree->left,val);
}
else if(val > tree->value)
{
tree->right=insert_tree(tree->right, val);
}
return tree;
}
void display_preorder(T *tree) //changed to accept parameter
{
if(tree)
{
printf("%d \n", tree->value);
display_preorder(tree->left);
display_preorder(tree->right);
}
}
int main(void)
{
insert_tree(tree,34);
insert_tree(tree,45);
insert_tree(tree,88);
insert_tree(tree,87);
display_preorder();
return 0;
}
It runs and executes without error, but, the output screen is blank.
Can somebody please point out the errors and mistakes?
Thank You.
The problem is in the insert_tree function.
Because your function gets only a pointer of a tree and not a pointer to a pointer you returned the value.
So, in the main you should place the tree equal to the function.
Your function gets the tree pointer by value and not by reference.
like this:
int main(void)
{
tree = insert_tree(tree, 34);
tree = insert_tree(tree, 45);
tree = insert_tree(tree, 88);
tree = insert_tree(tree, 87);
display_preorder(tree);
getchar();
return 0;
}
Related
There is a insert function which inserts in the tree recursively and display function for displaying the output.
the display() function is not displaying anything? Is there any error which I'm missing out?
please help
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{ int val;
struct node *left;
struct node *right;
} node;
node *root=NULL;
void insert(node *root1,int value)
{
if(root==NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->val=value;
temp->left=NULL;
temp->right=NULL;
root=temp;
root1=root;
return;
}
if(root1==NULL && root!=NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->val=value;
temp->left=NULL;
temp->right=NULL;
root1=temp;
return;
}
if(root1->val >value)
{
insert(root1->left, value);
}
else
{
insert(root1->right, value);
}
return;
}
void display(node *root1)
{
if(root1==NULL)
{
return;
}
while(root1 !=NULL)
{
printf("%d\n", root1->val);
display(root1->left);
display(root1->right);
return;
}
}
int main()
{
insert(root,4);
insert(root,12);
insert(root,2);
insert(root,55);
display(root);
return 0;
}
Actually I'm new to programming and trying to implement trees. New suggestions are also welcome! Thank you
//EDIT
void sayHi(int* nums){
printf("hello");
printf("my address is %d \n",nums);
printf("val of nums[2] is%d\n", nums[2]);
nums[2]=30;
}
void someFunct(int* nums, int numsSize){
nums[2]=50;
sayHi(nums);
printf("address is %d\n",nums);
printf("val of nums[2] is%d\n", nums[2]);
}
input i.e., nums =[0,0,0,0,0]
output for above code is
hellomy address is 16
val of arr[2] is50
address is 16
val of arr[2] is30
Here we are passing sayHi(nums)?and it still works? Address of nums is same in someFunct and sayHi?
Does passing arg like someFunct(&ptr) only happens for structures?
Method 1
In this method the root pointer is declared as a local variable in main, and the address of the pointer is passed to the insert function. This allows the insert function to change the value of root in main.
The downside of this method is that it involves some of the nastiest syntax in the C language, with *s and &s sprinkled everywhere, along with an inordinate number of mandatory parentheses.
void insert(node **root, int value)
{
if (*root == NULL)
{
node *temp=malloc(sizeof(node));
temp->val=value;
temp->left=NULL;
temp->right=NULL;
*root = temp;
}
else
{
if((*root)->val > value)
insert(&(*root)->left, value);
else
insert(&(*root)->right, value);
}
}
int main(void)
{
node *root=NULL;
insert(&root,4);
insert(&root,12);
insert(&root,2);
insert(&root,55);
display(root);
}
Method 2
Similar to method 1, this method also passes the address of the root pointer to the insert function, but to avoid some of the nasty syntax imposed by pointers-to-pointers, a local pointer item is used to access structure contents. This eliminates most of the *s and parentheses that were needed in method 1.
The downside of this method is that there are still &s sprinkled throughout the code, and it's easy to forget the line *root = temp; which updates the caller's pointer.
void insert(node **root, int value)
{
node *item = *root;
if (item == NULL)
{
node *temp=malloc(sizeof(node));
temp->val=value;
temp->left=NULL;
temp->right=NULL;
*root = temp;
}
else
{
if(item->val > value)
insert(&item->left, value);
else
insert(&item->right, value);
}
}
int main(void)
{
node *root=NULL;
insert(&root,4);
insert(&root,12);
insert(&root,2);
insert(&root,55);
display(root);
}
Method 3
In this method, we return the new root pointer from the insert function. Thus, the first function parameter can be a simple pointer. This eliminates the nasty syntax found in method 1. There are fewer *s, absolutely no &s, and no inordinate parentheses.
The downside to this method is that the return value from the function needs to be assigned to the appropriate pointer. That results in a couple of assignments in the insert function (at the recursive calls), as well as assignments in main.
node *insert(node *root, int value)
{
if (root == NULL)
{
root=malloc(sizeof(node));
root->val=value;
root->left=NULL;
root->right=NULL;
}
else
{
if(root->val > value)
root->left = insert(root->left, value);
else
root->right = insert(root->right, value);
}
return root;
}
int main(void)
{
node *root=NULL;
root = insert(root,4);
root = insert(root,12);
root = insert(root,2);
root = insert(root,55);
display(root);
}
Boilerplate
Here's the code that when combined with the insert and main functions from any method above gives a complete set of code that can be compiled and run.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{ int val;
struct node *left;
struct node *right;
} node;
void display(node *root)
{
if(root != NULL)
{
printf("%d\n", root->val);
display(root->left);
display(root->right);
}
}
I tried to search a tree node with a specific value in a binary search tree.
So I used recursion, but it didn't worked well.
I want to know what is wrong with the function.
Someone said I should return the function when I call it in itself.
It actually worked, but I don't understand why. Can someone explain to me how recursion really works and what if the return type is void?
Thank you!
typedef struct node
{
struct node* left;
struct node* right;
int val;
}treeNode;
int searchTree(treeNode *T, int key, treeNode *T1, treeNode** p)
{
if(!T)
{
*p=T1;
return 0;
}
else if(T->val==key)
{
*p=T;
return 1;
}
else if(T->val<key)
{
searchTree(T->right,key,T,p);
}
else
{
searchTree(T->left,key,T,p);
}
return 1;
}
you missed to return the value of the recursive call
if you need to do a recursive call this is not for nothing ;-)
int searchTree(treeNode *T, int key, treeNode *T1, treeNode** p)
{
if(!T)
{
*p=T1;
return 0;
}
else if(T->val==key)
{
*p=T;
return 1;
}
else if(T->val<key)
{
return searchTree(T->right,key,T,p);
}
else
{
return searchTree(T->left,key,T,p);
}
}
Note that because the recursion is terminal the compiler can remove it and produce a loop ...and you can do that by yourself too ;-)
This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 4 years ago.
I was working on trying to implement Binary Search Tree in C and had come across this issue. I have made my Insert function of void type and hence I do not have a variable which assigns the value of this call-back. When I run the program I do not see any output. Is this something to do with me not assigning my root node pointer once it has changed from NULL to pointing to a value?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *left, *right;
}Node;
void addToNode(Node *A, int value)
{
A->data=value;
A->left=NULL;
A->right=NULL;
}
void insert(Node *A, int value)
{
if(A==NULL)
{
A = (Node*)malloc(sizeof(Node));
addToNode(A, value);
// printf("Hello\n");
return;
}
else
{
if(value>A->data)
{
insert(A->right, value);
// printf("Hello\n");
return;
}
else if(value<A->data)
{
insert(A->right, value);
// printf("Hello\n");
return;
}
}
}
void inorder(Node *root)
{
if (root != NULL)
{
// printf("Hello\n");
inorder(root->left);
printf("%d \n", root->data);
inorder(root->right);
}
}
int main()
{
Node *root = NULL;
int A[]={45,32,56,23,11,89};
for(int i=0; i<6; i++) insert(root,A[i]);
inorder(root);
}
You should pass Node as pointer to pointer. Because you want to make alteration on the pointer itself.
void insert(Node **A, int value)
{
if(*A==NULL)
{
*A = (Node*)malloc(sizeof(Node));
addToNode(*A, value);
// printf("Hello\n");
return;
}
else
{
if(value>(*A)->data)
{
insert(&(*A)->right, value);
// printf("Hello\n");
return;
}
else if(value<(*A)->data)
{
insert(&(*A)->left, value);
// printf("Hello\n");
return;
}
}
}
The problem is not that your function is void, but that it takes the root pointer by value, rather than by pointer. That is why this assignment
A = (Node*)malloc(sizeof(Node));
remains local to your insert function; variable root of the main remains unassigned.
Modify your function to take the node by pointer:
void insert(Node **A, int value) {
if(*A == NULL) {
*A = malloc(sizeof(Node));
addToNode(*A, value);
return;
}
Node *root = *A;
if (value > root->data) {
insert(&root->right, value);
} else if (value < root->data) {
insert(&root->left, value);
}
}
Now the call in the main would look like insert(&root, A[i]);, so the assignment *A = malloc(sizeof(Node)) would modify root as necessary.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct node_{
int val;
struct node_ *left;
struct node_ *right;
}node;
node* insert(node* root,int val);
void inorder(node* root);
int main(void)
{
int i;
int item;
node* root = NULL;
srand(time(NULL));
for( i = 0; i < 10; i++)
{
item = rand()%15;
insert(root,item);
}
inorder(root);
return 0;
}
node* insert(node* root,int val)
{
if(root == NULL)
{
root = malloc(sizeof(node));
if(root!= NULL)
{
(root)->val = val;
(root)->left = NULL;
(root)->right = NULL;
}
else
printf("%d not inserted. No memory available.\n",val);
}
else
{
if(val < (root)->val)
{
insert((root->left),val);
}
if(val>root->val)
{
insert(((root)->right),val);
}
}
}
void inorder(node* root)
{
printf("%p",root);
if(root != NULL)
{
inorder(root->left);
printf("%3d",root->val);
inorder(root->right);
}
}
I am trying to create a binary tree and print out the values in order. However when I run this code the printf of the address prints out nil obviously meaning that my tree is empty so the printf and recursion below does not run. I cannot figure out where I went wrong, any suggestions or answers would be appreciated because I can't figure out why the root would be null after calling all of those inserts in main.
You pass root as a parameter to insert() (which says it is going to return something but doesn't). Inside insert you malloc your node and assign it to the local variable root. Nothing you ever do makes it out of the insert function.
Try returning something from insert, or using a global root.
As #JoshuaByer hints in the comments below, another approach is to make your insert method "pass by reference" so it can effectively modify what was passed to it.
void insert(node** rootp,int val)
{
if(*rootp == NULL)
{
*rootp = malloc(sizeof(node));
}
/* and so on */
If you don't understand what this is saying, google "Pass by reference in C" and I'm positive you'll get some good information.
In main() after declaring and initializing root (node* root = NULL;) you're never assigning it. In order to fix you should probably change the lin insert(root,item); to root = insert(root,item);.
Also note that although insert is defined as returning node * it does not return any value.
I am trying to write a code for finding distances between root and any node in binary tree. If the value of the node I am looking for is not in tree, I'll add it in tree and write its depth. I tried to write a code but somehow for root i get correct answer (depth=0) and for anything else I get value of depth = 1. I have been looking in code for quite a while now, so maybe you guys can help. Much appreciated.
#include <stdio.h>
#include <stdlib.h>
typedef struct b_tree t;
struct b_tree {
int value;
struct b_tree * right;
struct b_tree * left;
};
int add(t **root, t *bam, int pom) {
if ((*root) == NULL) {
*root = bam;
return pom;
}
else {
if((*root)->value == bam->value){
return pom;
}
else if((*root)->value > bam->value) {
pom++;
add(&(*root)->left, bam, pom);
}
else if ((*root)->value < bam->value) {
pom++;
add(&(*root)->right, bam, pom);
}
}
return pom;
}
int main() {
t *akt, *root = NULL;
int x=1, pom=0, depth;
while (x!=0){
scanf("%d", &x);
pom=0;
akt = (t *)malloc(sizeof(t));
akt->left = akt->right = NULL;
akt->value = x;
depth = add(&root, akt, pom);
printf("%d\n", depth);
}
return 0;
}
When debugging, the code gets in a unusual cycle (??). if pom is the value represented as my depth from root to node, what it does is, it gets to the correct answer (depth of node is 3, pom=3), but when I try to return pom; for unknown reason (to me) pom is lowered always to 1. Thanks for your help!
You are discarding the values returned by recursive calls to add(). Change the calls to:
return add(&(*root)->left, bam, pom);
...
return add(&(*root)->right, bam, pom);