I was new to trees in C. To learn more, I googled and found some nice example program. http://see-programming.blogspot.in/2013/03/insertion-deletion-and-traversal-in.html I copied it and ran it It worked perfectly. One of its functions was known as traverse. Its code is as follows:
void traverse(struct treeNode *node) {
if (node != NULL) {
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
}
return;
}
The whole program:
#include <stdio.h>
#include <stdlib.h>
struct treeNode {
int data;
struct treeNode *left, *right;
};
struct treeNode *root = NULL;
/* create a new node with the given data */
struct treeNode* createNode(int data) {
struct treeNode *newNode;
newNode = (struct treeNode *) malloc(sizeof (struct treeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return(newNode);
}
/* insertion in binary search tree */
void insertion(struct treeNode **node, int data) {
if (*node == NULL) {
*node = createNode(data);
} else if (data < (*node)->data) {
insertion(&(*node)->left, data);
} else if (data > (*node)->data) {
insertion(&(*node)->right, data);
}
}
/* deletion in binary search tree */
void deletion(struct treeNode **node, struct treeNode **parent, int data) {
struct treeNode *tmpNode, *tmpParent;
if (*node == NULL)
return;
if ((*node)->data == data) {
/* deleting the leaf node */
if (!(*node)->left && !(*node)->right) {
if (parent) {
/* delete leaf node */
if ((*parent)->left == *node)
(*parent)->left = NULL;
else
(*parent)->right = NULL;
free(*node);
} else {
/* delete root node with no children */
free(*node);
}
/* deleting node with one child */
} else if (!(*node)->right && (*node)->left) {
/* deleting node with left child alone */
tmpNode = *node;
(*parent)->right = (*node)->left;
free(tmpNode);
*node = (*parent)->right;
} else if ((*node)->right && !(*node)->left) {
/* deleting node with right child alone */
tmpNode = *node;
(*parent)->left = (*node)->right;
free(tmpNode);
(*node) = (*parent)->left;
} else if (!(*node)->right->left) {
/*
* deleting a node whose right child
* is the smallest node in the right
* subtree for the node to be deleted.
*/
tmpNode = *node;
(*node)->right->left = (*node)->left;
(*parent)->left = (*node)->right;
free(tmpNode);
*node = (*parent)->left;
} else {
/*
* Deleting a node with two children.
* First, find the smallest node in
* the right subtree. Replace the
* smallest node with the node to be
* deleted. Then, do proper connections
* for the children of replaced node.
*/
tmpNode = (*node)->right;
while (tmpNode->left) {
tmpParent = tmpNode;
tmpNode = tmpNode->left;
}
tmpParent->left = tmpNode->right;
tmpNode->left = (*node)->left;
tmpNode->right =(*node)->right;
free(*node);
*node = tmpNode;
}
} else if (data < (*node)->data) {
/* traverse towards left subtree */
deletion(&(*node)->left, node, data);
} else if (data > (*node)->data) {
/* traversing towards right subtree */
deletion(&(*node)->right, node, data);
}
}
/* search the given element in binary search tree */
void findElement(struct treeNode *node, int data) {
if (!node)
return;
else if (data < node->data) {
findElement(node->left, data);
} else if (data > node->data) {
findElement(node->right, data);
} else
printf("data found: %d\n", node->data);
return;
}
void traverse(struct treeNode *node) {
if (node != NULL) {
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
}
return;
}
int main() {
int data, ch;
while (1) {
printf("1. Insertion in Binary Search Tree\n");
printf("2. Deletion in Binary Search Tree\n");
printf("3. Search Element in Binary Search Tree\n");
printf("4. Inorder traversal\n5. Exit\n");
printf("Enter your choice:");
scanf("%d", &ch);
switch (ch) {
case 1:
while (1) {
printf("Enter your data:");
scanf("%d", &data);
insertion(&root, data);
printf("Continue Insertion(0/1):");
scanf("%d", &ch);
if (!ch)
break;
}
break;
case 2:
printf("Enter your data:");
scanf("%d", &data);
deletion(&root, NULL, data);
break;
case 3:
printf("Enter value for data:");
scanf("%d", &data);
findElement(root, data);
break;
case 4:
printf("Inorder Traversal:\n");
traverse(root);
printf("\n");
break;
case 5:
exit(0);
default:
printf("u've entered wrong option\n");
break;
}
}
return 0;
}
When I ran the program it worked perfectly. But when I analyzed the traverse function, I could not understand it. When you call the traverse function from the main, you pass the root to it as in this program. But when the node is not NULL, it continues printing the tree as more data is left to print. But every time the node is not NULL, the line traverse (node->left); calls the function once again before printing the node. Thus I do not understand how the whole tree gets printed. It would be helpful if someone could explain.
Let's take this binary tree as an example.
binary tree
How the whole tree gets printed?
Each time we call traverse function, we will print the data of *node.
Traverse process is a recursive process in which functions dealing with root node will call functions dealing with root's left-child and right-child. For example, traverse(15) will call traverse(5) and traverse(16), and traverse(5) will call traverse(3) and traverse(12).
Recuration ends with leaf nodes and every node is visited and printed.
Why the result is in-order?
In each call of void traverse(struct treeNode *node), we could regard *node as the root of a subtree. Following codes mean data of *node won't be printed until recurse of its left-child returns.
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
And traverse(node->left) returns only when its left-child and right-child are traversed, childs of node->left will also printed before *node. So, all nodes in left sub-tree of *node will be printed before *node, and all nodes in right sub-tree of *node will be printed after it.
For example, traverse(12) calls traverse(10) before print 12, traverse(10) calls traverse(6) and traverse(6) calls traverse(7). Since 7 is a leaf node, traverse(7), traverse(6) and traverse(10) returns in order. Then traverse(12) print 12 and calls traverse(13).
We could get in-order result of 6 7 10 12 13
Related
i have implemented a tree in C:
struct node
{
char *key;
struct node *left, *right;
};
// A utility function to create a new BST node
struct node *newNode(char *item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// A utility function to do inorder traversal of BST
void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
printf("%s\n", root->key);
inorder(root->right);
}
}
/* A utility function to
insert a new node with given key in
* BST */
struct node *insert(struct node *node, char *key)
{
/* If the tree is empty, return a new node */
if (node == NULL)
return newNode(key);
/* Otherwise, recur down the tree */
if (strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search
tree, return the node
with minimum key value found in
that tree. Note that the
entire tree does not need to be searched. */
struct node *minValueNode(struct node *node)
{
struct node *current = node;
/* loop down to find the leftmost leaf */
while (current && current->left != NULL)
current = current->left;
return current;
}
/* Given a binary search tree
and a key, this function
deletes the key and
returns the new root */
struct node *deleteNode(struct node *root, char *key)
{
// base case
if (root == NULL)
return root;
// If the key to be deleted
// is smaller than the root's
// key, then it lies in left subtree
if (strcmp(key, root->key) < 0)
root->left = deleteNode(root->left, key);
// If the key to be deleted
// is greater than the root's
// key, then it lies in right subtree
else if (strcmp(key, root->key) > 0)
root->right = deleteNode(root->right, key);
// if key is same as root's key,
// then This is the node
// to be deleted
else
{
// node with only one child or no child
if (root->left == NULL)
{
struct node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct node *temp = root->left;
free(root);
return temp;
}
// node with two children:
// Get the inorder successor
// (smallest in the right subtree)
struct node *temp = minValueNode(root->right);
// Copy the inorder
// successor's content to this node
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
return root;
}
I have defined a function that takes the Tree as input and deletes a node from it if a condition is met:
void applyFilter(struct node *Tree)
{
if (Tree != NULL)
{
applyFilter(Tree->left);
applyFilter(Tree->right);
for (short i = 0; i < MAX_CONSTRAINTS; i++)
{
if (strchr(Tree->key, constraints[i].letter) != NULL)
{
// delete the word from the tree
Tree = deleteNode(Tree, Tree->key);
break;
}
}
}
}
But i got segmentation fault.
The main goal is to make it work, with as little memory as possible (running).
I think I understand the problem, and it is caused by recursion, because if I delete a node it will give me an empty tree.
If you can give me an example, even a different one i will be really gratefull, because i worked on it a lot, but i am totally stucked.
Thank you!
It happens in minValueNode() after the call of the deleteNode(), because result that the Tree is empty
It happens in minValueNode() after the call of the deleteNode(), because result that the Tree is empty
Basically you already understand what the problem is. You will need to check whether the tree is empty and default the value to something inside minValueNode before you start looping. Because the loop assumes that you have something and if you happen to have nothing, then it's a faulty assumption and causes segfault.
The display function I've used for printing the tree only seems to print the first element and not the rest. I don't know why I suspect the insert function which I've used without recursion might be the cause but can't seem to understand where it goes wrong. Any explanation on how to correct it or where the code fails would be helpful. Thanks.
#include <stdio.h>
#include<stdlib.h>
void insert(int data_add,struct tree *temp);
void display(struct tree *temp);
struct tree
{
int data;
struct tree *left;
struct tree *right;
} *root = NULL;
int main()
{
int data_add,n;
while(1)
{
printf("\n\n1.Add\n2.Display\n4.Exit\n");
scanf("%d",&n);
switch(n)
{
case 1: printf("\nEnter the element to add ");
scanf("%d",&data_add);
insert(data_add,root);
break;
case 2: printf("The nos are: ");
display(root);
break;
/*case 3: printf("The nos are: ");
reversedisplay(root);*/
case 4: exit(1);
break;
default: printf("\nChoose a appropriate option");
}
}
}
void insert(int data,struct tree *temp)
{
struct tree *current;
current = (struct tree*) malloc(sizeof(struct tree));
current->data = data;
if(root == NULL)
{
root = current;
current->left = NULL;
current->right = NULL;
}
else
{
while(temp!=NULL)
{
if(data<temp->data)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = current;
current->left = NULL;
current->right = NULL;
}
}
void display(struct tree *temp)
{
if(temp == NULL)
return;
display(temp->right);
display(temp->left);
printf("%d",temp->data);
}
The problem in your code is that while inserting a node you are not making the new inserted node as the left or right child of any node, because of which the new node is not actually inserted in your tree.
Your code where things go wrong -
temp = current;
current->left = NULL;
current->right = NULL;
After coming out of the loop, temp is NULL , now current is assigned to temp, but there is no way to reach the new node from any other node in the tree, because it is not left/right child of any node in the tree.
Here I present the correct code for the insert function -
void insert(int data,struct tree *temp)
{
struct tree *current;
current = (struct tree*) malloc(sizeof(struct tree));
current->data = data;
current->left = NULL;
current->right = NULL;
if(root == NULL)
{
root = current;
current->left = NULL;
current->right = NULL;
}
else
{
struct tree *par=temp; //par is used to keep track of node whose left
//or right child will be the new node.
while(temp!=NULL)
{
par=temp;
if(data<temp->data)
temp=temp->left;
else temp=temp->right;
}
// The below part is used to make the new node as left or right child
// of the appropriate node.
if(data<par->data)
par->left=current;
else
par->right=current;
}
}
Moreover , slight change in your display function, change your printf statement to -
printf("%d ",temp->data); .
In previous version all the node values would be printed without no spaces giving an impression that only one number is printed.
The problem is in the insert function. You never link the new node to the old one. You would need to use pointers keep the address of the right or left node. Instead of that, you only copy the address of current node in the local temp variable. You code should be:
...
else
{
t = &temp;
while(*t!=NULL)
{
if(data<(*t)->data)
{
t = &(*t)->left;
}
else
{
t = &(*t)->right;
}
}
*t = current; // actually copy current in right of left of last node
current->left = NULL;
current->right = NULL;
}
But that's not all, in order to display the elements in order, you should change display to:
void display(struct tree *temp)
{
if(temp == NULL)
return;
display(temp->left); // left side first
printf("%d",temp->data); // then current
display(temp->right); // finally right side
}
I have previously posted about this same topic. I am self-learning data structures using MIT Open Courseware. I'm doing the 6.S096-Introduction to C/C++ course and attempting the fourth assignment.
It is based on binary search trees and I gave it a try. I wanted to print the values for debugging but kept getting different executions each time.
One time, the cycle doesn't complete and the other time, it goes on to infinity. The debugging block also relates to the other function(find_node_data) I have to complete. So if I can figure what's wrong here, I can easily finish the find_node_data. I have commented a few things to see if it affects anything. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int node_id;
int data;
struct node* left;
struct node* right;
}node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node* newNode(int data,int node_id){
node* new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->node_id= node_id;
new_node->right= new_node->left=NULL;
return new_node;
}
node* insert_node(node* root, int node_id, int data) {
if(root==NULL)
return newNode(data,node_id);
else{
node* cur;
if(node_id<root->node_id){
cur=insert_node(root->left,data,node_id);
root->left=cur;
}
else if(node_id>root->node_id){
cur=insert_node(root->right,data,node_id);
root->right=cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*int find_node_data(node* root, int node_id) {
node* current;
for( current = root->; current->next!=NULL;
current= current->next){
if(current->data == data) return current;
}
return NULL;
}
*/
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T,data,node_id;
printf("Print yo cases");
scanf("%d", &T);
node* root = NULL;
while(T-->0){
printf("Type yo numnums no. %d:",T);
scanf("%d %d",&data,&node_id);
root=insert_node(root,data,node_id);
}
node *lol;
node *king;
for(lol=root;lol->left!=NULL;lol=lol->left){
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ",lol->node_id);//,king->node_id);
//}
}
return 0;
}
To find the node_data you can use recursion to find the node.
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
And then get the data for the node e.g. get the data for node with node_id 42:
printf("node data %d", find_node_data(root, 42)->data);
Full program below (I can't guarantee its correctness but maybe you can?)
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int node_id;
int data;
struct node *left;
struct node *right;
} node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node *newNode(int data, int node_id) {
node *new_node = (node *) malloc(sizeof(node));
new_node->data = data;
new_node->node_id = node_id;
new_node->right = new_node->left = NULL;
return new_node;
}
node *insert_node(node *root, int data, int node_id) {
if (root == NULL)
return newNode(data, node_id);
else {
node *cur;
if (node_id < root->node_id) {
cur = insert_node(root->left, data, node_id);
root->left = cur;
}
else if (node_id > root->node_id) {
cur = insert_node(root->right, data, node_id);
root->right = cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*
int find_node_data_old(node *root, int node_id) {
node *current;
for (current = root->; current->next != NULL;
current = current->next) {
if (current->data == data) return current;
}
return NULL;
}*/
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
void print(node *np) {
if (np) {
print(np->left);
printf("(%d, %d)", np->node_id, np->data);
print(np->right);
}
}
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d", find_node_data(root, 42)->data);
return 0;
}
Test
Print yo cases3
Type yo numnums no. 2:22 42
Type yo numnums no. 1:21 41
Type yo numnums no. 0:20 40
executed!
42 executed!
41 (40, 20)(41, 21)(42, 22)
node data 22
You may also use Jonathan Leffler's improved recursion to find the node:
node *find_node_data2(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else if (root->node_id > node_id)
return find_node_data(root->left, node_id);
else
return find_node_data(root->right, node_id);
}
Both functions return the correct values as seen in the second test.
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d\n", find_node_data(root, 42)->data);
printf("node data find_node_data2 %d", find_node_data2(root, 42)->data);
return 0;
}
Test 2
Print yo cases3
Type yo numnums no. 2:11 12
Type yo numnums no. 1:13 14
Type yo numnums no. 0:20 42
(12, 11)(14, 13)(42, 20)
node data 20
node data find_node_data2 20
I've been trying to implement a simple binary search tree in C just as an exercise. I can insert elements into the tree, but at certain points (I haven't been able to figure out where) I'm getting a segmentation fault.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *left;
struct node *right;
int key;
};
void insert(struct node *treeNode, int key);
void outputTree(struct node *root);
int main(){
//Store how many numbers the user will enter
printf("How many numbers will you enter? > ");
int numNumbers;
scanf("%d", &numNumbers);
//Create a root node
struct node root;
root.key = -1; //-1 Means the root node has not yet been set
root.right = NULL;
root.left = NULL;
//Now iterate numNumbers times
int i;
for(i = 1; i <= numNumbers; ++i){
int input;
scanf("%d", &input);
insert(&root, input);
}
outputTree(&root);
return 0;
}
void insert(struct node *treeNode, int key){
//First check if the node is the root node
if((*treeNode).key == -1){
printf("Root node is not set\n");
(*treeNode).key = key; //If the root node hasn't been initialised
}
else {
//Create a child node containing the key
struct node childNode;
childNode.key = key;
childNode.left = NULL;
childNode.right = NULL;
//If less than, go to the left, otherwise go right
if(key < (*treeNode).key){
if((*treeNode).left != NULL){
printf("Left node is not null, traversing\n");
insert((*treeNode).left, key);
}
else {
printf("Left node is null, creating new child\n");
(*treeNode).left = &childNode;
}
}
else {
//Check if right child is null
if((*treeNode).right != NULL){
printf("Right node is not null, traversing...\n");
insert((*treeNode).right, key);
}
else {
printf("Right node is null, creating new child\n");
(*treeNode).right = &childNode;
}
}
}
}
void outputTree(struct node *root){
//Traverse left
if((*root).left != NULL){
outputTree((*root).left);
}
printf("%d\n", (*root).key);
if((*root).right != NULL){
outputTree((*root).right);
}
}
As of writing this question, I've just had the thought, are the child nodes being created on the stack, so when the recursive calls return, the references in the tree are pointing to a struct that no longer exists?
What is wrong here?
Thank you
You create childs node on the stack by static allocation. When the insert method is finished, the child reference become invalid.
You should use dynamic allocation with malloc.
struct node *new_node(int key, struct node *left, struct node *right) {
struct node *this = malloc(sizeof *this);
this->key = key;
this->left = left;
this->right = right;
return this;
}
don't forget to free all of your allocations with the free function.
edit :
so to create the root just use
struct node *root = new_node(-1, NULL, NULL);
I am implementing the binary search tree with some operations ( new node, search, insert and display).
It results in following warning.
binarytree.c:70: warning: assignment makes pointer from integer without a cast
binarytree.c:72: warning: assignment makes pointer from integer without a cast
binarytree.c:73: warning: return makes integer from pointer without a cast
binarytree.c: At top level:
binarytree.c:78: warning: conflicting types for ‘printInoder’
binarytree.c:47: warning: previous implicit declaration of ‘printInoder’ was here
binarytree.c: In function ‘NewNode’:
binarytree.c:122: warning: return makes pointer from integer without a cast
Undefined symbols for architecture x86_64:
"_newNode", referenced from:
_main in cckg2mll.o
_insert in cckg2mll.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
You will see my source code here below but I wish to hear your suggestions. I fully understand the Binary trees functions but I think it is not related to any algorithm but it is a programming problem.
Source Code
It is really long code but I cannot reduce it for your guys.
#include <stdlib.h>
#include <stdio.h>
#define false 0
#define true 1
struct Node
{
int data;
struct Node *left, *right;
}*node,*root;
int main(void)
{
root = (struct Node *)malloc(sizeof(struct Node));
int option = 1;
int choice,value,target,newvalue;
while(option)
{
printf("Enter your choice \n");
scanf("%d\n",&choice);
switch(choice)
{
case 1:
printf("Enter the a new value\n");
insert(root,value);
scanf("%d\n",&value);
break;
case 2:
printf("Enter the traget \n");
scanf("%d\n",&target);
lookup(root,target);
break;
case 3:
printf("Enter the new node \n");
scanf("%d\n",&newvalue);
newNode();
break;
case 4:
printInoder();
break;
}
printf("Enter 0 or 1\n");
scanf("%d\n",&option);
}
}
int insert(struct Node *node ,int data)
{
// 1. If the tree is empty, return a new, single node
node = (struct Node *)malloc(sizeof(struct Node));
if (node == NULL)
{
return(newNode(data));
}
else
{
// 2. Otherwise, recur down the tree
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
return(node); // return the (unchanged) node pointer
}
}
void printInoder()
{
root = (struct Node *)malloc(sizeof(struct Node));
if (root != NULL)
{
printInoder(root->left);
printf("%d ",root->data);
printInoder (root->right);
}
}
int lookup(struct Node *node, int target)
{
node = (struct Node *)malloc(sizeof(struct Node));
// 1. Base case == empty tree
// in that case, the target is not found so return false
if (node == NULL)
{
return(false);
}
else
{
// 2. see if found here
if (target == node->data) return(true);
else
{
// 3. otherwise recur down the correct subtree
if (target < node->data)
return(lookup(node->left, target));
else return(lookup(node->right, target));
}
}
}
struct Node *NewNode(int x)
{
node =(struct Node *)malloc(sizeof(struct Node)); // "new" is like "malloc"
node->data = x;
node->left = NULL;
node->right = NULL;
return(x);
}
So, the biggest issue is that you ignore data types. insert function returns int but whenever you assign its return value or even return something inside this function, the variables you use are pointers instead - so change return type of insert to struct Node *node.
Also, in case 4 part, you use function printInoder which is declared and defined after calling it (below main function) so that is why it warns you that you should at least declare this function before main.
Finally, inside insert function, you call newNode but this function is called NewNode and it is also declared and defined below main.
You called the following function using newNode not NewNode. Also, move the * off of the NewNode part.
struct Node *NewNode(int x)
{
node =(struct Node *)malloc(sizeof(struct Node)); // "new" is like "malloc"
node->data = x;
node->left = NULL;
node->right = NULL;
return(x);
}
Your insert function returns a node pointer but is declared with an int return type.
Also, you need to declare functions above where they are called the first time. add a declaration statement to the top of the page for your functions to work.
return_type function_name(params);
Finally, rename your function to printInOrder() instead of printInoder()
Your code has many errors.
I've edited it a bit:
#include <stdlib.h>
#include <stdio.h>
#define false 0
#define true 1
struct Node
{
int data;
struct Node *left, *right;
};
void insert(struct Node **node, int data);
int lookup(struct Node *node, int target);
void printInoder(struct Node *root);
struct Node *NewNode(int x);
int main(void)
{
struct Node *root = NULL;
int option = 1;
int choice, value, target;
while (option)
{
choice = value = target = 0;
printf("Enter your choice \n");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Enter the a new value\n");
scanf("%d", &value);
insert(&root, value);
break;
case 2:
printf("Enter the traget \n");
scanf("%d", &target);
printf("%d\n", lookup(root, target));
break;
case 3:
printf("Printing\n");
printInoder(root);
printf("\n");
break;
}
printf("Enter 0 or 1\n");
scanf("%d", &option);
}
return 0;
}
void insert(struct Node **root, int data)
{
// 1. If the tree is empty, return a new, single node
struct Node *node = NewNode(data);
if (*root == NULL)
{
*root = node;
return;
}
// 2. Otherwise, recur down the tree
if (data <= (*root)->data)
insert(&(*root)->left, data);
else
insert(&(*root)->right, data);
}
void printInoder(struct Node *root)
{
if (root == NULL) return;
printInoder(root->left);
printf("%d ", root->data);
printInoder(root->right);
}
int lookup(struct Node *root, int target)
{
// 1. Base case == empty tree
// in that case, the target is not found so return false
if (root == NULL)
{
return(false);
}
// 2. see if found here
if (target == root->data) return(true);
// 3. otherwise recur down the correct subtree
if (target < root->data)
return(lookup(root->left, target));
else return(lookup(root->right, target));
}
struct Node *NewNode(int x)
{
struct Node *node= malloc(sizeof *node);
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
Try it, and take a look at the changes in the code.