Issues with recursive bool function - c++

bool search(double x, TreeNode *t)
{
if (t->value == x)
return true;
else if (x < t->value)
search(x, t->left);
else if (x > t->value)
search(x, t->right);
return false;
bool search(double num)
{
TreeNode *ptr = root;
return search(num, ptr);
}
The search function with 2 arguments is a private member function of a binary tree class that uses recursion to search for a value. The other search function is called to call the recursive function. This code does not work. I have displayed the value of the recursive function and it does not return 0 or 1. I have no idea why. Also, if I send in a value that is not in the tree, the program crashes so I get no errors to help me.

Your recursion never stops if you don't find an element.
If it's found in the root, you return true.
If it's found somewhere else, you return false.
You need to
Handle the empty tree, and
Return something meaningful when recursing.
Like
bool search(double x, const TreeNode *t)
{
if (t == nullptr)
return false;
else if (t->value == x)
return true;
else if (x < t->value)
return search(x, t->left);
else
return search(x, t->right);
}
or
bool search(double x, const TreeNode *t)
{
return t != nullptr
&& ( t->value == x
|| (t->value < x && search(x, t->left))
|| (t->value > x && search(x, t->right)));
}

Related

access to an object member passed by unique_ptr

I wrote the following code to check if a node is in the BST:
bool BST_Node :: BST_Find(unique_ptr<BST_Node> root, int key){
if(!root || root->key == INT_MIN) return false;
if(root->key == key) return true;
else if(key < root->key) BST_Find(move(root->left), key);
else BST_Find(move(root->right), key);
}
root parameter is passed using move(bst) where bst in an unique_ptr.
The problem is when it tries to read root->key: even if the key is present in the tree, this method returns false.
I've tried to use the debugger and root can not be accessed.
Here is the code that uses this method:
auto bst = make_unique<BST_Node>();
for(int i=0; i<n; i++){
key = rand();
if(!bst->BST_Find(move(bst), key)) {
bst->BST_Insert(move(bst), key, "");
}
}
Try this
bool BST_Node :: BST_Find(unique_ptr<BST_Node> const &root, int key){
if(!root || root->key == INT_MIN) return false;
if(root->key == key) return true;
else if(key < root->key) return BST_Find(root->left, key);
else return BST_Find(root->right, key);
}
BST_Find(bst, 42) // no move

How to check if a tree is a BST?

I have to check if a tree is a binary search tree. I'm doing this with an inorder traversal with a temporary array that collects the values. I have to check if the array is ascending order and if it is then I return true:
bool myisBST(Node* node, std::vector<int> v);
bool myisBST(Node* node)
{
return myisBST(node, std::vector<int>());
}
bool myisBST(Node* node, std::vector<int> v)
{
if (node)
{
if (node->left)
return myisBST(node->left, v);
v.push_back(node->data);
if (node->right)
return myisBST(node->right, v);
}
return std::is_sorted(v.begin(), v.end());
}
When binary tree is this:
50
/ \
25 75
/ \ / \
1 12 62 -99
As you can see, the -99 makes this not a binary search tree, but it is still returning true. Is there something wrong with my implementation?
Demo
Two problems:
In myisBST, you are passing v by value, not by reference, so when you pass the vector on recursively, the changes that are made to it don't change its value in the calling method. Simply change the function signature to bool myisBST(Node* node, std::vector<int>& v) to fix this.
The value you should be returning is whether the vector is sorted (as you do in the last line of your method), but instead you are returning prematurely by writing return myisBST(node->left, v); and return myisBST(node->right, v);. You're not actually interested in the return values of these methods; you're just using them to fill the vector inorder. Remove the return from both of these lines.
Following these two fixes, your method works.
First of all, you should probably pass the vector by reference or each recursive call will get a copy and thus the original vector will probably be empty.
Second, you don't even need to create the vector first and then do the check, you can just check the BST property at each node, i.e., the root must be bigger than the left child and smaller than the right child, e.g.,
bool isBST(const Node* root, vector<int>* v) {
if (!root) { return true; }
bool leftBST = true;
if (root->left) {
if (root->data > root->left->data) {
leftBST = isBST(root->left, v);
} else {
// the current node violates the BST precondition
return false;
}
}
// push the root
v->push_back(root->data);
// return false if left subtree is not a BST
if (!leftBST) return false;
if (root->right) {
if (root->data < root->right->data) {
// return whether or not the right subtree is a BST
return isBST(root->left, v);
} else {
// the current node violates the BST precondition
return false;
}
}
// everything good, this is a BST
return true;
}
C++ Program to check if tree is BST or not
struct Node
{
int data;
struct Node* left, *right;
};
bool IsBST(Node* ObjNode)
{
bool leftBST = false;
bool rightBST = false;
if( ObjNode->left != null && ObjNode-left < objNode->data)
{
leftBST = IsBST(ObjNode->left)
}
else if( ObjNode->left == null)
{
leftBST = true;
}
else if( ObjNode->left != null && ObjNode-left >= objNode->data)
{
leftBST = false;
}
if( ObjNode->left != null && ObjNode-left < objNode->data)
{
rightBST = IsBST(ObjNode->right)
}
else if( ObjNode->right == null)
{
rightBST = true;
}
else if( ObjNode->right != null && ObjNode-right >= objNode->data)
{
rightBST = false;
}
return (leftBST && rightBST );
}
In the previous solution, they are keeping a list of the inorder traversal, you really don't need it, you can keep checking with the last traversed element and keep moving forward.
Following solution is the fastest
class Solution {
int lastval = Integer.MIN_VALUE;
int count = 0;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
boolean left = isValidBST(root.left);
if(!left){
return false;
}
int rootVal = root.val;
if(rootVal == -2147483648 && count == 0 ){
rootVal = rootVal + 1;
}
if( rootVal <= lastval){
return false;
}
count ++;
lastval = root.val;
boolean right = isValidBST(root.right);
if(!right){
return false;
}
return true;
}
}

Why does this recursive function behave different than intended?

I am writing a binary tree and I am stuck on a search function that takes a value x and determines if it is a leaf in the tree or not.
Here is what I have:
bool search(Node<T>* &currentNode, const T& x) const
{
/* Base Case */
if ( currentNode != nullptr && (leaf(currentNode) == true) && currentNode->data == x )
{
return true;
}
/* Recursive Case */
else {
if (currentNode != nullptr)
{
search(currentNode->left, x);
search(currentNode->right, x);
}
//If first if condition is not met for all values then value must not exist
return false;
}
bool leaf(Node<T>* currentNode) const
{
if (currentNode != nullptr)
{
return ((currentNode->left == nullptr && currentNode->right == nullptr) ? true : false);
}
else
{
return true;
}
}
The code always returns false, why is the first IF statement never triggered?
EDIT:
Code calling search:
for (int i = 0; i < 101; i++)
if ((t.search(i) == true) ? cout << "LEAF FOUND: " << i << endl : cout << " NOT A LEAF: " << i << endl);
dealing with recursion can be tricky :D.
unless the root node is a leaf your code will always return return false
your code returns true to the function that made the call not all the way back to the original caller ( before recursion)
let's say your tree had three elements and the item was in the left leaf
so in the root node you called yourself with the left node so it returned true to the caller ( the root node) , the root node does nothing with this and just continue executing.
this can be simply solved simply by adding an if statement to check for the returned value of the functions you called
if (currentNode != nullptr)
{
if(search(currentNode->left, x)) return true;
if(search(currentNode->right, x)) return true;
}
return false;
Because you don't return the boolean from the search method back:
if (currentNode != nullptr)
{
search(currentNode->left, x);
search(currentNode->right, x);
}
You always will return false.

Binary search tree lazy deletion

I want to implement a lazy deletion into my code. I have added a boolean value to keep track of when a node is "deleted"/marked deleted. I am unsure of what methods to actually change. Here are my remove and insert methods. I attempted the remove, but not the insert. I know for sure that the insert method will have to do a lot of checking. Please advise.
template<class Comparable>
bool search_tree<Comparable>::remove(treeNode<Comparable> * &root,
const Comparable &x) {
if (root == NULL)
return false;
if (x < root->data)
return remove(root->lftChild, x);
if (root->data < x)
return remove(root->rtChild, x);
root->deleted = true;
return true;
}
template<class Comparable>
bool search_tree<Comparable>::insert(treeNode<Comparable> * &root,
const Comparable &x) {
if (root == NULL) {
root = new treeNode<Comparable>(x, NULL, NULL);
return true;
} else if (x < root->data)
return insert(root->lftChild, x);
else if (root->data < x)
return insert(root->rtChild, x);
return false;
}
Your insert function should work as is unless x is equal to an item that has been deleted then it wont get inserted. If x is equal to root->data you need to make sure deleted is false.
And your remove function looks like it should work fine.

binary search tree "contains" function

Trying to make a contains function for a binary tree.
The function looks like this:
bool contains(bt_node* top, int data) {
if (top == NULL) return false;
else {
if (data == top->data) return true;
else if (data < top->data) contains(top->left, data);
else if (data > top->data) contains(top->right, data);
}
}
The function is returning false for a value that actually is in the tree. Can anyone help?
Thanks,
Max
You forgot to return the value of the recursive calls to contains. So the return value of your function is undefined. Change it to the following to make it work:
bool contains(bt_node* top, int data) {
if (top == NULL) return false;
else {
if (data == top->data)
return true;
else if (data < top->data)
return contains(top->left, data); //you forgot to return the value
else if (data > top->data)
return contains(top->right, data);
}
}
You could have done slightly better though:
bool contains(bt_node* top, int data) {
if (top == NULL) return false;
if (data == top->data) return true;
if (data < top->data) return contains(top->left, data);
return contains(top->right, data);
}