Search node recursion error binary search tree - C++ - c++

to keep this is as minimal as possible, I have a recursive binary tree function like this:
template <class T>
bool Bst<T>::searchTree(const nodeType<T>* p, const T& searchItem) const
{
if(p == nullptr)
{
cout << "Cannot search an empty tree." << endl;
return false; //If root is nullptr, that means there is no root node hence no binary tree to begin with
}
else
{
if(p->info == searchItem)
{
return true;
}
else if(p->info > searchItem)
{
return searchTree(p->rLink, searchItem);
}
else
{
return searchTree(p->lLink, searchItem);
}
//Sets the root node to the pointer current
}
}
This function is made use of by another function:
template <class T>
bool Bst<T>::searchTreeRecursive(const T& searchItem) const
{
return searchTree(root, searchItem);
}
And I use it in one of my main methods like this:
if(dateTree.searchTreeRecursive(newDate))
{
cout << "Date has been found." << endl;
}
else
{
cout << "Date not found." << endl;
}
Where newDate is an object of a class called Date, and dateTree is a binary search tree that holds dates inside it. The BST is fine after insertion because when doing traversal to output all the values are there.
My problem is, my searchTree function meets the condition that p==nullptr (p is root) and returns false, even when I know the date I've entered exists in the BST. Can anyone spot out problems with my code and help me out?
EDIT: For the very first date value in my BST, if i search for that it returns correctly. For every value after the first in the BST, its apparently nullptr.
Thanks

Related

Why does this code fragment giving me a segmentation fault?

I am writing a binary search tree and this function called Search takes a value x and searches the nodes in the tree and returns whether it is a leaf or not.
bool search(Node<T>* &currentNode, const T& x) const
{
//~ cout << "CURRENT NODE DATA: " << currentNode->data << " : ";
/* FUNCTION: Searches for variable that is passed in X and checks if this value is a leaf or not */
//Left Subtree Search
if (x < binTree<T>::root->data)
{
if ((leaf(currentNode)) == true)
{
return true;
}
else
{
search(currentNode->left, x);
}
}
//Right Subtree Search
else if (x >= binTree<T>::root->data)
{
//If node in right subtree is a node check
if ((leaf(currentNode)) == true)
{
return true;
}
else
{
search(currentNode->right, x);
}
}
//Return false if the node is not a leaf
return false;
} //END OF SEARCH FUNCTION
bool leaf(Node<T>* currentNode) const
{
return ((currentNode->left == nullptr && currentNode->right == nullptr) ? true : false);
}
The seg fault occurs when I recursively call the search function with new updated node. The binary tree is initialized with 100 values and it starts searching at the root.
This code
if (x < binTree<T>::root->data)
is checking against root, note currentNode, so the test will never change. So if your x value is less than root->data you will keep trying to recurse through currentNode->left until you either hit a leaf (if you are lucky) or you hit a node with a NULL left pointer, in which case you will recurse with currentNode as NULL, which will cause a segfault in leaf when it tries to check for currentNode->left
You should be checking against currentNode. You should also be returning the return value of your search recursive calls
You have to declare
bool leaf(Node<T>* currentNode) const
BEFORE search
Easy fix, copy and paste bool leaf(Node<T>* currentNode) const; before your search function

How to find the leaf of a binary tree?

I am writing a binary tree with a search function. The function is supposed to take an argument x which denotes the value to be searched and once it is found, determine if it is a leaf or not. If the value is not found, the search functions returns false.
Here is what I have which gives me a seg fault and has been just giving me false returns for every value from 1 to 100. The binary tree is initalized with 100 values.
bool search(Node<T>* &currentNode, const T& x) const
{
//~ cout << "CURRENT NODE DATA: " << currentNode->data << " : ";
/* FUNCTION: Searches for variable that is passed in X and checks if this value is a leaf or not */
//Left Subtree Search
if (x < currentNode->data)
{
if ((leaf(currentNode)) == true)
{
return true;
}
else
{
search(currentNode->left, x);
}
}
//Right Subtree Search
else if (x >= currentNode->data)
{
//If node in right subtree is a node check
if ((leaf(currentNode)) == true)
{
return true;
}
else
{
search(currentNode->right, x);
}
}
//Return false if the node is not a leaf
return false;
} //END OF SEARCH FUNCTION
void remove(Node<T>* &currentNode, const T& x)
{
}
bool leaf(Node<T>* currentNode) const
{
if (currentNode != nullptr)
{
return ((currentNode->left == nullptr && currentNode->right == nullptr) ? true : false);
}
else
{
return true;
}
}
Additionally, the leaf function returns true when currentNode is nullptr, assuming the check for nullptr in search is resolved. Is this the behavior you want for a pointer pointing to a non-existent leaf?
In your search function, you recourse on the child nodes without seeing if they're nullptr first... Then you try to de reference the data element still without checking for null.

BST - inserting + C++

I'm trying to work on a binary search tree data structure, but I cannot seem to accomplish inserting anything into the tree. Every time my program calls the insert function, it believes there is nothing in tree. Here are the 2 classes:
template<typename T>
class TreeNode{
public:
T m_data;
TreeNode* m_right;
TreeNode* m_left;
TreeNode<T>(const T& data, TreeNode<T>* right, TreeNode<T>* left) : m_data(data), m_right(right), m_left(left){};
};
template<typename T>
class MyBSTree : public AbstractBSTree<T>{
protected:
TreeNode<T>* m_root;
int m_size;
And here is the function:
void rec_insert(TreeNode<T>* root, const T& x){
if(root == NULL){
cout << "Inserting here" << endl;
TreeNode<T>* tmp = new TreeNode<T>(x, NULL, NULL);
root = tmp;
}
else if(x < root -> m_data){
cout << "Inserting left" << endl;
rec_insert(root -> m_left, x);
}
else if(x > root -> m_data){
cout << "Inserting right" << endl;
rec_insert(root -> m_right, x);
}
if(root == NULL)
cout << "WHAT IS HAPPENING?" << endl;
cout << "resizing" << endl;
m_size++;
};
The output for inserting a couple of items is this:
Inserting here
resizing
Inserting here
resizing
I really have no clue what is going on here, any help would be greatly appreciated.
You need to do a bit of research on pass by reference and pass by value.
You pass a pointer into your insert method - you can only change the value of root locally - any change you make won't persist beyond the function call. You need to pass by reference to allow root to be changed and see that change outside the rec_insert() method.
Another approach may be to refactor your code to return the root value from rec_insert().

B-tree recursive search C++

This function recursively calls itself to search the Btree and returns true if the value is found, and false if it is not found. I also want it to cout "not found" one time at the end if it is not found. It works fine except that it says "not found" numerous times (everytime it goes down a level it says not found) since it calls itself.
bool lookup(int val, btnode *n) //returns true/false if value is in btree
{
if (n==NULL) return false; //empty tree
for (int i=0;i< n->count;i++) //check in present node for the val
if(n->value[i]==val)
{
flag = true;
return true;
}
//check in child node
for(int i =0;i<n->count;i++) //check for child node
{ if(val < n->value[i])
{ cout<<"checking a different node."<<endl;
lookup(val,n->child[i]);
}
}
if(val > n->value[(n->count)-1])
{
cout<<"searching a right subtree"<<endl;
lookup(val, n->child[n->count]);
}
if (flag==false)
return false;
else return true;
}
bool lookup2(int val, btnode *n)
{
if(lookup(val, n)==false)
{
cout<<"not found"<<endl;
return false;
}
else
{
cout<<"Found it"<<endl;
return true;
}
}
You probably want to make an auxiliary method that calls this lookup function, and does the printing. Something like:
bool lookup_print(int val, btnode *n) {
bool found = lookup(val, n);
if (found) {
cout << "Found it!" << endl;
} else {
cout << "Not found..." << endl;
}
return found;
}
Also, you need to make sure that your recursive calls are returning their values if they do find a node. So everywhere you recurse, you'll want something like:
bool found = lookup(val,n->child[i]);
if (found) {
return found;
}

Search Binary Tree function not work c++

and I was trying to implement a binary searching tree:
template <typename T>
bool Tree<T>::search(TreeNode<T> *ptr, const T &key) {
if (ptr == 0) {
cout<<"No such data: "<<key<<" in the tree"<<endl;
return false;
}
else{
if (ptr->data == key) {
cout<<"Find a node whose data is "<<key<<endl;
return true;
}
else if (ptr->data < key) return search(ptr->leftPtr,key);
else return search(ptr->rightPtr,key);
}
}
But the result always returns false no matter the tree contains the key value or not.
Can u guys help me check the code? I tried debug, but still do not know.
Thank you!
Your traversal comparator for left-tree descending is backwards. As such, as soon as you incorrectly descend into the right tree you stand no chance of ever finding that value. Only the root, and root only, will ever be found correctly.
This:
if (ptr->data < key)
return search(ptr->leftPtr,key);
else
return search(ptr->rightPtr,key);
Should read like this:
if (key < ptr->data) // <== note key is LESS THAN node.
return search(ptr->leftPtr,key);
else
return search(ptr->rightPtr,key);
That said, consider this:
template <typename T>
bool Tree<T>::search(TreeNode<T> *ptr, const T &key)
{
if (ptr == 0) {
cout<<"No such data: "<<key<<" in the tree"<<endl;
return false;
}
if (key < ptr->data)
return search(ptr->leftPtr, key);
else if (ptr->data < key)
return search(ptr->rightPtr, key);
cout<<"Found a node whose data is "<< key << endl;
return true;
}