Finding an element in Binary Search Tree - c++

I wrote this code to find a node in BST.The code works fine for Nodes found but the code crashes when a node is not found.
What is the possible error in my code?
TreeNode* fetch(TreeNode*root,int d)
{
if(root->data==d)
{
return root;
}
else if(root==NULL)
{
return NULL;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
TreeNode* temp;
temp=fetch(root,d);
if(temp->data)
{
cout<<temp->data<<" FOUND";
}
else if(temp==NULL)
{
cout<<"Not Found";
}

You need to adjust your ordering in your fetch() function. Right now, it will error if root==NULL because it first checks if the data in the potentially non-existent node is equal to d. Fixed is as follows:
TreeNode* fetch(TreeNode*root,int d)
{
if(root==NULL)
{
return NULL;
}
else if(root->data==d)
{
return root;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
Additionally you need to reorder your check at the bottom for the same reason:
if(temp==NULL)
{
cout<<"Not Found";
}
else
{
cout<<temp->data<<" FOUND";
}

The problem is with the sequence of conditions put in if else if ladder.
Please read the comments I have written on the lines of your code
TreeNode* fetch(TreeNode*root,int d)
{
if(root->data==d) /* if d doesn't exists, root becomes
null and dereferencing a null
gives error, i.e, null->data is
error. So, first root=null should
be checked*/
{
return root;
}
else if(root==NULL)
{
return NULL;
}
else if(d<root->data)
{
return fetch(root->left,d);
}
else if(d>root->data)
{
return fetch(root->right,d);
}
}
TreeNode* temp;
temp=fetch(root,d);
if(temp->data) // temp=NULL should be must codition
{
cout<<temp->data<<" FOUND";
}
else if(temp==NULL)
{
cout<<"Not Found";
}

You have no case if a node is a leaf. Before you call fetch(root->left,d) or fetch(root->right,d) make sure the node has a left or right element by checking if(root->(left/right) != NULL) before you call fetch again. If they do == NULL, then you can return NULL as you've navigated to the bottom of the tree and didn't find your element.

Related

how can i delete node in binary search tree in c++ and dev c++

i tried to delete node that i choose one. my deletion code couldn't work. where is my fault? there is a header file and a source file. they are connected together but i don't know my code is couldn't work ?
node *IkiliAgac::sil(node *kok,int no){
if(kok==NULL)
return kok;
if(kok->no>no)
{
kok->sol=sil(kok->sol,no);
return kok;
}
else if(kok->no<no){
kok->sag=sil(kok->sag,no);
return kok;
}
if(kok->sol==NULL)
{
node* temp=kok->sag;
delete kok;
return temp;
}
else if(kok->sag==NULL)
{
node* temp=kok->sol;
delete kok;
return temp;
}
else {
node* succparent=kok;
node* succ=kok->sag;
while(succ->sol!=NULL)
{
succparent=succ;
succ=succ->sol;
}
if (succparent!=kok)
succparent->sol=succ->sag;
else
succparent->sol=succ->sag;
kok->no=succ->no;
delete succ;
return kok;
}
}

Binary search tree two similar functions producing garbage

I've got this call
productTree.displayNode(productTree.newsearchTree(search, productTree.Root()));
Calling these functions
void Tree::displayNode(Node* node) {
if (node != NULL) {
cout << node->productdata << endl;
}
}
Node* Tree::newsearchTree(string search, Node* node) {
if (node != NULL) {
newsearchTree(search, node->left);
if (search == node->productdata.getName()) {
return node;
}
newsearchTree(search, node->right);
}
}
Node* Root() { return root; };
Which produces a garbage output when trying to display the returned node.
And yet, I can traverse my tree and display it easily this way:
This call:
productTree.Inorder(productTree.Root());
Functions:
void Tree::Inorder(Node* node) {
if (node != NULL) {
Inorder(node->left);
displayNode(node);
Inorder(node->right);
}
}
And where I am confused is how are they different?
Edit: Thank you for your help, I modified the code as below and it works fine now:
Node* Tree::newsearchTree(string search, Node* node) {
if (node != NULL) {
newsearchTree(search, node->left);
if (search == node->productdata.getName()) {
return node;
}
newsearchTree(search, node->right);
}
return NULL;
}
void Tree::displayNode(Node* node) {
if (node != NULL) {
cout << node->productdata << endl;
}
else if (node == NULL) {
cout << "Product not found" << endl;
}
}
Yep, that's still broken. This finally fixed it I believe:
Node* Tree::newsearchTree(string search, Node* node) {
if (node != NULL) {
if (search == node->key) {
return node;
}
if (search < node->key) {
return newsearchTree(search, node->left);
}
else {
return newsearchTree(search, node->right);
}
}
else return NULL;
}
Let me add comments inline to make it clear what your Tree::newsearchTree does.
Node* Tree::newsearchTree(string search, Node* node) {
if (node != NULL) {
newsearchTree(search, node->left); // burn CPU but leaves no side effect
if (search == node->productdata.getName()) {
return node; // return node only if the root node equals 'search'
}
newsearchTree(search, node->right); // burn CPU without side effect
}
// In majority of the cases (root node != 'search'): return nothing.
}
Because typically newsearchTree() returns nothing, when you call productTree.displayNode(productTree.newsearchTree(...)) you basically print garbage.

not able to create Binary search tree in c++

My InsertInTree function is not working properly, and I am not able to figure out my problem. Please suggest changes I can make (but I don't want to use recursion).
It takes values from the structure and the function GetNewNode returns the node with left and right pointer as NULL:
public:
void InsertInTree(int piData)
{
Node*newNode = NULL;
newNode=GetNewNode(piData);
if(root==NULL)
{
root=newNode;
return;
}
Node*temp = root;
while(temp!=NULL)
{
if(newNode->data<=temp->data)
{
temp=temp->left;
}
else
{
temp=temp->right;
}
}
temp=newNode;
return;
}
bool SearchNum(int piSearch)
{
if(root==NULL)
{
return false;
}
Node*temp=root;
while(temp!=NULL)
{
if(temp->data==piSearch)
{
return true;
}
else if(piSearch<=temp->data)
{
temp=temp->left;
}
else
{
temp=temp->right;
}
}
if(temp==NULL)
{
return false;
}
else
{
return true;
}
}
Assuming root is global. you should use one more node i.e. *pre (previousnode).
*pre=NULL;
while(temp!=NULL){
if(newnode->data<=temp->data){
pre=temp;
temp=temp->left;
}else{
pre=temp;
temp=temp->right;
}
}
if(newnode->data<=pre->data)
pre->left=newnode;
else
pre->right=newnode;
this will solve the problem..
The following should fix your issue:
void InsertInTree(int piData)
{
Node* newNode = GetNewNode(piData);
Node** temp = &root;
while (*temp != NULL)
{
if (newNode->data <= (*temp)->data)
{
temp = &(*temp)->left;
}
else
{
temp = &(*temp)->right;
}
}
*temp = newNode;
}

Inserting 4 or 5 numbers in binary tree but getting just 3 numbers in the output

This is part of a lab for school dealing with recursion and binary tree. If I go to insert 4 or 5 numbers and output the result I get just 3 numbers back. Here is the code for insert:
Node *insert(Node *t, int key) {
Node *insertParent;
Node *result=NULL;
if (t!=NULL) {
result=search(t,key,insertParent);
} else {
t=new Node;
t->data=key;
t->leftchild=NULL;
t->rightchild=NULL;
return t;
}
if (result==NULL) {
if (insertParent->data>key) {
insertParent->leftchild=new Node;
insertParent->leftchild->data=key;
insertParent->leftchild->leftchild=NULL;
insertParent->leftchild->rightchild=NULL;
return insertParent->leftchild;
} else if (insertParent->data<key) {
insertParent->rightchild=new Node;
insertParent->rightchild->data=key;
insertParent->rightchild->leftchild=NULL;
insertParent->rightchild->rightchild=NULL;
return insertParent->rightchild;
}
} else
return NULL;
}
But I believe the trouble is within the search function, specifically the node pointer by reference parent:
Node* search(Node *t, int key, Node *&parent) {
if (t!=NULL) {
parent=t;
if (t->data==key)
return t;
else if (t->data>key)
return search(t->leftchild,key,t);
else
return search(t->rightchild,key,t);
} else
return NULL;
}
I have a function that outputs the tree and have checked it against a tree I built manually and it works fine:
void inorder(Node *t)
{
if (t!=NULL) {
if (t->leftchild!=NULL)
inorder(t->leftchild);
cout << t->data << ", ";
if (t->rightchild!=NULL)
inorder(t->rightchild);
}
}
Not looking for an answer just looking for an area I should look at.
Your suspicion is correct. Trace how the top-level 'parent' parameter gets updated once you search more than one node deep.
Node* search(Node *t, int key, Node *&parent)
{
if(t!=NULL)
{
parent=t;
if (t->data==key)
return t;
else if (t->data>key)
return search(t->leftchild, key, parent); // use “parent” because you want to assign parent to this variable
else
return search(t->rightchild,key, parent);
}
else return NULL;
}
So I discovered my problem was with the search function. It did have to do with the reference parent node variable. I had to use four else/ifelse statement to be able to decide which way to go, recursively or not.
Node* search(Node *t, int key, Node *&parent) {
if (t!=NULL) {
if (t->data==key) {
parent=NULL;
return t;
} else if (t->data>key && t->leftchild!=NULL) {
return search(t->leftchild,key,parent); // think this needs returned
} else if (t->data>key && t->leftchild==NULL) {
parent=t;
return NULL;
} else if (t->data<key && t->rightchild!=NULL) {
return search(t->rightchild,key,parent); //think this needs returned
} else if (t->data<key && t->rightchild==NULL) {
parent=t;
return NULL;
}
} else {
parent=NULL;
return NULL;
}
}
This change in the search function necessitated a change in the insert function:
Node *insert(Node *t, int key) {
Node *insertParent=NULL;
Node *result=NULL;
if (t!=NULL) {
result=search(t,key,insertParent);
} else {
t=new Node;
t->data=key;
t->leftchild=NULL;
t->rightchild=NULL;
return t;
}
if (insertParent==NULL && result!=NULL) {
return NULL;
} else if (insertParent!=NULL && result==NULL) {
//key not found need to add
if (insertParent->data>key) {
insertParent->leftchild=new Node;
insertParent->leftchild->data=key;
insertParent->leftchild->leftchild=NULL;
insertParent->leftchild->rightchild=NULL;
return insertParent->leftchild;
} else {
insertParent->rightchild=new Node;
insertParent->rightchild->data=key;
insertParent->rightchild->leftchild=NULL;
insertParent->rightchild->rightchild=NULL;
return insertParent->rightchild;
}
}
}
Thanks to all who helped...
(Also: I answered my own question. Is this what I should of done or should I of edited my post? Would think that people would rather see the whole process and not have me delete the old non-working code...)

How Can This Recursive Function Work?

I can't figure out how this works, to my mind, once it gets to the answer it doesn't do anything with it.
Node* FindNode(Node *rootNode, int data)
{
if (!rootNode)
return NULL;
else
{
if (rootNode->data == data)
return rootNode;
else
{
FindNode(rootNode->left, data);
FindNode(rootNode->right, data);
}
}
}
It doesn't. It should be:
Node* FindNode(Node *rootNode, int data) {
if (!rootNode) {
return NULL;
}else if (rootNode->data == data) {
return rootNode;
}else if (data < rootNode->data) {
return FindNode(rootNode->left, data);
}else{
return FindNode(rootNode->right, data);
}
}
Note the extra return statements, and the extra else if clause.
EDIT — To sum up the comments below: The only reason the code you posted could be working is if an odd combination of compiler-implementation details and test data came together in your favour. You should definitely fix the problem rather than keeping the code how it was.
This is assuming that the FindNode returns on the first match.
Node* FindNode(Node *rootNode, int data)
{
Node *ptr;
if (!rootNode)
return NULL;
else
{
if (rootNode->data == data)
return rootNode;
else
{
ptr = NULL;
// if either left or right child is there
if(rootNode->left || rootNode->right)
{
// if not found in left subtree
if(NULL == (ptr = FindNode(rootNode->left, data))){
// check in right subtree
ptr = FindNode(rootNode->right, data);
}
}
return ptr;
}
}
}