Binary tree lookup - c++

I am building a binary tree in C++ using recursion and I can't figure out why I can't return an Item, it's probably a simple thing I'm over looking but I've been looking at it so long I can't figure it out.
BST::Item * BST::lookup(Key k)
{
return(lookupRec(k, root));
}
BST::Item * BST::lookupRec(Key k, Node* n)
{
if (k == n->key)
{
return n->item; //problem is here
}
else if (k > n->key)
{
lookupRec(k, n->rightChild);
}
else if (k < n->key)
{
lookupRec(k, n->leftChild);
}
else
{
return nullptr;
}
}
to add some context Item is using Item = std::string; so I call the lookup with a key and it calls the worker function and should return the item when the key and root key match, but it won't return the n->item because it says there is no suitable conversion from BST::Item to BST::Item*
any help would be appreciated, thanks

Where you call lookupRec() recursively, you should also return, otherwise, you will return nothing from that function instance: return lookupRec(k, n->rightChild);
And as #UnholySheep already mentioned: return the right type, as the compiler tells you: return &(n->item);

Related

c++ how to get depth of a binary tree recursively

I wrote a code that suposed to return the depth of a binary tree from the root to the node who called the function. using recursive way but I faced a problem about how to count the number of times that the function gets called so I whould know how much convexity I passed. Someone know how can I do that?
int BSNode::getDepth(const BSNode& root) const
{
if (this != nullptr)
{
if (root.getData() > this->_data)
{
this->getDepth(*root.getRight());
}
else if (root.getData() < this->_data)
{
this->getDepth(*root.getLeft());
}
else if (root.getData() == this->_data)
{
// return the number that the function counted
}
}
else
{
return 0;
}
}
You should at least return something in every case. And when you arrive at the intended node (having the data you are looking for), then return 0. In all other cases, return what you get from recursion plus 1. If the value is not found then indeed -1 should be returned. And if this -1 is coming back from recursion, it should be returned like that also to the caller (without adding 1).
Here is the code adapted:
int BSNode::getDepth(const BSNode& root) const
{
int temp;
if (this != nullptr)
{
if (root.getData() > this->_data)
{
temp = this->getDepth(*root.getRight());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() < this->_data)
{
temp = this->getDepth(*root.getLeft());
return temp == -1 ? -1 : temp + 1;
}
else if (root.getData() == this->_data)
{
return 0;
}
}
else
{
return -1;
}
}

Error: control may reach end of non-void function in C++

I cannot figure out why this error is happening: error: "control may reach end of non-void function" even when "else" statement is present at the end.
Here is the code:
bnode* binsert(bnode *h,int k){
bnode *temp=new bnode;
if(h==NULL)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h=temp;
return h;
}
else if(h->L==NULL && k<h->num)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h->L=temp;
return h;
}
else if(h->R==NULL && k>h->num)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h->R=temp;
return h;
}
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
}
You need to return the results of recursive calls, it's not done automatically.
You can also simplify your code a bit by adding a constructor:
bnode::bnode(int v)
: num(v),
L(nullptr),
R(nullptr)
{
}
and since you're already handling the case of a null parameter, you don't need special cases for null children:
bnode* binsert(bnode *h,int k)
{
if(h == nullptr)
{
h = new bnode(k);
}
else if(k < h->num)
{
h->L = binsert(h->L, k);
}
else if(k > h->num)
{
h->R = binsert(h->R, k);
}
return h;
}
because this last 2 conditions:
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
may occur and no return is given...
you need to be sure the function returns a value no matter what the condition evaluates....
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
In the else if and else cases for your code, if you reach here, you do not return a value, and the behavior is undefined if you try to use this value.
You probably want to add a return h; in the two branches.

BST search function returns true on one machine and false on another

I have a BST program and this is my search function that returns true if the specified data (d) is found in a node. When it is called, node *s points to the root node of the tree.
This program works perfectly when I compile it on my university's virtual machine, but returns false when I compile and run it on my macbook. What would be causing a completely different output? I added a line to print out the data of each node it passes through while searching, and it finds the node with the correct data, but still returns false.
I'd appreciate any help, I can't think of a reason why this function would break under a different compiler.
This is the information on my mac compiler
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
This is the information on my virtual machine compiler
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Here is my BST search function:
bool bst::search(int d, node *s){
cout << s->data << endl;
if(s->data == d){
curRoot = s;
return 1;
}
else if(d > s->data){
if(s->right == NULL)
return 0;
else{
if(s->right->data == d)
pRoot = s;
search(d,s->right);
}
}
else{
if(s->left == NULL)
return 0;
else{
if(s->left->data == d)
pRoot = s;
search(d,s->left);
}
}
}
There are several problems/redundancies in your current function.
First of all, you need to return the value of your recursive function search() right to the top of the stack.
The redundancies are in the form of multiple NULL checks, multiple data equality checks.
A condensed form of the function to serve the purpose is as follows-
bool bst::search(int d, node *s){
if(s == NULL) {
return 0;
}
if(s->data == d) {
return 1;
}
if(d > s->data) {
return search(d,s->right);
}
else {
return search(d,s->left);
}
}
You seem to think the search function should return only once... that's indeed how it should be for an iterative implementation. So let's look at one, based on sray's simplification.
bool bst::search(int d, const node *s)
{
while (s) {
if(s->data == d) return 1;
if(d > s->data) {
s = s->right;
}
else {
s = s->left;
}
}
return 0;
}
This was possible because the recursion was tail-recursive -- we can just replace the arguments and loop.
Recursion itself doesn't work that way. It works just like any other function call. If you called sqrt inside your function, you wouldn't think that sqrt would replace your function, rather you would use the result in your calculation. Same thing when you call your own function. And sometimes recursive results need to be used for further calculation. Consider this function to count the nodes in a tree:
bool count(const node *s)
{
if (s)
return count(s->left) + 1 + count(s->right);
return 0;
}
It would do you no good to have the deepest calls set the return value for the whole tree.

Getting Error When Trying to Call Function from Another Header File (C++)

I have developed a dual-parameter binary search tree, and am now trying to apply it to create a dictionary. My find function inside the tree works as it should, however, when I try and call it inside of my dictionary class, I get a compiler error "expected primary-expression before '>' token." Can anyone help me understand what's going wrong? I'm not very familiar with trying to call functions from other files.
This is my find function from the binary search tree, inside of bst.h
V & find (K key)
{
TreeNode<K,V> *traverseFind;
traverseFind = root;
unsigned int compareTraverseToHeight = 0;
while (compareTraverseToHeight < heightCount)
{
if (traverseFind == NULL) // Fallen off
{
keyFinder = 0;
break;
}
else if ( key == traverseFind->key )// Found key
{
keyFinder = 1;
break;
}
else if ( key < traverseFind->key )
{ .
traverseFind = traverseFind->left;
}
else
{
traverseFind = traverseFind->right;
}
compareTraverseToHeight++;
} // end of loop
if(keyFinder ==0)
{
throw key_not_found_exception();
}
cout<<"RETURNED "<<traverseFind->value<<endl;
return traverseFind->value;
}
And the dictionary:
#include bst.h
template <class K, class V> class Dictionary
{
public:
BinarySearchTree<K,V> wiktionary;
Dictionary()
{
}
~Dictionary()
{
}
V & find (K key)
{
return(wiktionary.find(<V>)); //this is the issue
}
private:
};
#endif
And the application in main:
int main()
{
Dictionary<string, int> d;
int val = d.find("abc");
if (val != 15)
throw dictionary_tester_exception(__FILE__, __LINE__);
return 0;
}
The problem is that <V> specifies a template argument but you are attempting to pass it to BinarySearchTree::find() as function argument instead. The find member function isn't templated so even if you attempted to pass it as a template argument that wouldn't work either. Based on the supplied code you should be passing key as the argument to find like so
return(wiktionary.find(key));

Subset sum recursion with c++

This is one of the solution of getting true or false from given set and target value
bool subsetSumExists(Set<int> & set, int target) {
if (set.isEmpty()) {
return target == 0;
} else {
int element = set.first();
Set<int> rest = set - element;
return subsetSumExists(rest, target)
|| (subsetSumExists(rest, target- element));
}
}
However, this solution will return true or false value only. How is it possible to get the element that involve in the subset(set that add together will equal to target) as well?
Do I have to use dynamic programming? Coz as i know.. recursion is building up stack actually and after the function return the value, the value inside the frame will be discarded as well.
So, is it possible to get the elements that add up equal to the target value.
Is passing an object a solution of the problem?
Thank you
First of all you can optimize your program a little bit - check if target is 0 and if it is always return true. Now what you need is to have somewhere to store the elements that you have already used. I will show you a way to do that with a global "stack"(vector in fact so that you can iterate over it), because then the code will be easier to understand, but you can also pass it by reference to the function or avoid making it global in some other way.
By the way the stl container is called set not Set.
vector<int> used;
bool subsetSumExists(Set<int> & set, int target) {
if (target == 0) {
cout << "One possible sum is:\n";
for (int i = 0; i < used.size(); ++i) {
cout << used[i] << endl;
}
return true;
} else if(set.empty()) {
return false;
}else {
int element = set.first();
Set<int> rest = set - element;
used.push_back(element);
if (subsetSumExists(rest, target- element)) {
return true;
} else {
used.pop_back();
}
return subsetSumExists(rest, target);
}
}
Hope this helps.