If/Else statement returns - c++

This section of code keeps throwing an error, "not all control paths return a value". I'm not entirely sure how to rewrite this so that I can fix the error. Other than the returns, this is what I need this section of code to do. Should I create a new variable that I declare within the if/else statement and then have the return for that variable right before the ending bracket?
node * LList::search(int srchKey)
{
node * p = head;
while (p != NULL)
{
if (p->key == srchKey)
{
return p;
}
else
{
return NULL;
}
p = p->next;
}
}

If head is NULL, search() will exit without reaching any return statement. The return value will be indeterminate. That is what the compiler is complaining about.
If head is not NULL, search() will check only the first node and then return a value, it will not search the whole list. Because of that, the return NULL; statement should not be inside the loop at all. It will exit search() as soon as it encounters an element that doesn't match, rather than continuing to the next element in the list.
This is similar to the problem I describe in Searching array reports "not found" even though it's found.
You should wait until the loop ends before doing return NULL;. If you get there, it means the item being searched for really wasn't found.
node * LList::search(int srchKey)
{
node * p = head;
while (p != NULL)
{
if (p->key == srchKey)
{
return p;
}
p = p->next;
}
return NULL;
}

You need another return statement after the while loop. One possible code path is that the program never enters the while loop. A simple
return NULL;
should fix it.
EDIT: Also, your loop will only ever make one pass through. I would remove the (if p == NULL) block; it is useless. I see your intent, but the way to implement it is how I described above.

when while condition is false, then you do not have return.
Add a return outside while in case you do not enter the loop.
Moreover, p = p->next; will never be executed because you exit the loop before reaching it because of if-else.
Regarding the logic, It seems to me that you do not need the else part at all. try to omit it and place return NULL before the end of the routine.

Related

what is wrong with this reverse linklist code?

var reverseList = function(head) {
function reverse(cur,pre){
if(!cur) return pre
next = cur.next
cur.next = pre
return reverse(next,head)
}
return reverse(head.next,head)
}
I tried a recursion way to write this,
this code output is not correct running, whats wrong with this code?
This is what i think:
If we go by your logic for let's say this case (1->2->3->null), then end result is - first node has address of second node in its 'next' & second node has address of first in its 'next'. So, a loop is formed (1->2 and 2->1). If you want to print such a list, it'll end up in an infinite loop kind of situation in an online platform.
As Thomas Mailund has correctly pointed out, null list case also needs to be covered.
I'd also suggest you to keep your variable names distinct from each other to avoid confusion.
(e.g. you used 'next' as variable name in your inner function which is used already for linked list).
Taking these factors into consideration, here's the rectified working version of your code:
var reverseList = function(head) {
var r = null;
function reverse(p, q) {
q.next = r;
r = q;
if (p == null) return q;
return reverse(p.next, p);
}
return (!head) ? head : reverse(head.next,head)
}

function that returns the number of nodes in a certain level of a binary search tree

I have to create a function getNodesatLevel that returns the number of nodes at a level, however, I'm getting a "may reach end of void function" error. This is for a Binary Search tree, and I'm required to use recursion for this function.
int TreeType::getNodesAtLevel(TreeNode * &node, int level, ItemType * mainArr)
{
int currentLevel = 0;
int NodeCount = 1;
if(currentLevel == level)
{
NodeCount++;
return NodeCount;
}
else if(currentLevel != level)
{
currentLevel++;
if(node->left != NULL)
getNodesAtLevel(node->left, level, mainArr);
if(node->right != NULL)
getNodesAtLevel(node->right, level, mainArr);
}
}
The error is basically what it says on the tin: your function can reach the end without returning a value.
To see why, let's just look at your outer if statement:
if(node->left != NULL)
//...
if(node->right != NULL)
//...
//...
What happens if both node->left and node->right are null? You don't handle this case at all. That's a bug.
Secondly (and arguably most importantly) you call yourself recursively, but don't do anything with the return value of your function. You don't return it, and you don't save it for later either. That means nothing really happens to it. It just gets lost.
Because of this, your function won't return this value at all. That creates situations in which nothing is returned.
So, to fix this, figure out what you want to do with the recursive return value of your function and either a) save it in a temporary variable, or b) simply return it. Which one you choose will depend on what you want your function to count.
Also, make sure you return a value even if both sides of the tree are NULL.

printing the contents of a Binary Search Tree recursively?

void MovieTree::printMovieInventory(MovieNode* node)
{
if(node)
{
while(node->rightChild!=NULL or node->leftChild!=NULL)
{
std::cout<<"Movie:"<<node->title<<" "<<node->quantity<<std::endl;
if(node->rightChild)
{
printMovieInventory(node->rightChild);
}
if(node->leftChild)
{
printMovieInventory(node->leftChild);
}
}
}
else
{
std::cout<<"No movies in list!"<<std::endl;
}
}
I'm not sure if this function is causing my issue or if it's my adding function but I feel as though the logic to this is correct. Am I missing something?
Edit::
My issue is that it's resulting in an infinite loop and it's not properly printing all associated children of the tree
Use of while in the function is wrong. It needs to be if. Otherwise, the function never breaks out of the while loop.
FWIW, that function can be simplified to:
void MovieTree::printMovieInventory(MovieNode* node)
{
if(node)
{
std::cout<<"Movie:"<<node->title<<" "<<node->quantity<<std::endl;
printMovieInventory(node->rightChild);
printMovieInventory(node->leftChild);
}
}
In addition to the problem with the while loop, this can also never print leaf nodes, as you don't print the node itself if it doesn't have either a left or a right child.
while(node->rightChild!=NULL or node->leftChild!=NULL)
{
std::cout<<"Movie:"<<node->title<<" "<<node->quantity<<std::endl;
it should be
if(node)
print node
if left
recurse left
if right
recurse right
Couple of Things here.
From the code as i understand, you are trying to print in a pre-order fashion.
the While Loop is unnecessary and that is what is causing the infinite loop
Lets say you have two nodes root and root->left
your function will print root, call the function recursively on root' = root->right (will not print anything this time because root'->left is NULL and root'->right is NULL). Then the function print(root') returns to its caller which is print(root). This time it will not exit out of the while Loop because the while condition is always true, ergo the infinite Loop.
you can simply do this
Print(root)
cout << root;
if(root->right != NULL)
Print(root->right);
if(root->left != NULL)
Print(root->left);
TO display "No Movies" just check if root == NULL before calling this recursive function Print(root);

How to add children to BST

I'm trying to make/create a BST, but it doesn't seem to work properly. I've literally been sitting here for hours trying to figure out what's going on. It's gotten to the point where I've drawn a million diagrams to figure this out, yet my code fails me. I need to pass in a root node into a function. Then I need to traverse through the tree until I find that the parent string parameter of the function coincides with the tree parent node's string. If I do find it, I must insert the string into the parent, and create two new children from that parent. If I can't find the parent string, then I return false.
bool insertNode(BSTNode *n, char* parentQ, char* leftQ, char* rightQ)
{
if(n->Q == parentQ)
{
n->left = new BSTNode(leftQ);
n->right = new BSTNode(rightQ);
return true;
}
else if(n->Q != parent)
{
insertNode(n->left,parentQ,leftQ,rightQ);
insertNode(n->right,parentQ,leftQ,rightQ);
}
else
return false;
}
Also I need to make another method that takes the tree that I have established, and corrects the strings. So the method modifies the parent string, if found, and looks at its children, if found, and replaces those strings with those found in the method parameters. It's sort of like adding a subtree without screwing the entire tree up. Thanks in advance!
bool changeNode(BSTNode *n,char* parentQ, char* leftQ, char* rightQ)
{
if(n->Q == leftQ)
{
n->Q = parentQ;
n->left = new BSTNode(leftQ);
n->right = new BSTNode(rightQ);
return true;
}
else if(n->Q == rightQ)
{
n->Q = parentQ;
n->left = new BSTNode(leftQ);
n->right = new BSTNode(rightQ);
return true;
}
else if(n->Q != leftQ)
{
changeNode(n->left,parentQ,leftQ, rightQ);
}
else if(n->Q != rightQ)
{
changeNode(n->right,parentQ,leftQ,rightQ);
}
return false;
}
You didn't even mention what the error was, example input / expected output, but shouldn't you be checking whether the current node actually has a left and right child, before calling the function with those children?
else if(n->Q != parentQ) // <--- you have a typo in this line, "parent"
{ // (and you don't even need the 'if')
insertNode(n->left,parentQ,leftQ,rightQ);
insertNode(n->right,parentQ,leftQ,rightQ);
// in this case you return nothing! corrupted return value
}
^ this seems very error-prone, especially null-pointer. You should turn it into something like:
else
{
if(n->left != NULL) // take a look at nullptr if you have C++11
if(insertNode(n->left,parentQ,leftQ,rightQ)) return true;
if(n->right != NULL)
if(insertNode(n->right,parentQ,leftQ,rightQ)) return true;
return false;
}
Otherwise your true return never gets propagated back beyond the first return, so then you're always returning false unless in the only case where the root of the tree is actually the node you were searching for.
Also, do not compare two char arrays using ==, unless n->Q is actually an std::string. You should use if(strcmp(n->Q, parentQ) == 0) otherwise.
Your second piece of code, however, is just a mess. You need to take a better look at what exactly will be happening on your else if's and see if it is actually doing what you want (hint: it isn't), as you currently only execute at most 1 of the code blocks, even if more than one condition is true.

BST insert in C++

I'm learning C++ and writing a binary search tree. The following is the code I wrote for my insert method.
BSTNode * BST::Insert(const std::string & v) {
BSTNode *n = !root ? root = new BSTNode(v) : Insert_Helper(v,root);
if(n) size++;
return n;
}
BSTNode * BST::Insert_Helper(const std::string & v, BSTNode *n) {
if(!n->value.compare(v))
return NULL; // already have v
else if(n->value.compare(v) > 0) // v goes to the left
if(n->left) return Insert_Helper(v,n->left);
else return n->left = new BSTNode(v);
else // v goes to the right
if(n->right) Insert_Helper(v,n->right);
else return n->right = new BSTNode(v);
}
The bug I'm getting goes like this: It all works fine and dandy, until I try to insert a duplicate node. It doesn't add a new node, yet it increments count.
By observing in GDB, I've found that when I try to add a string that I already have, Insert_Helper works correctly and returns NULL. This value however (on my machine) is something like 0x6, which is out of bounds of course, but not 0x0 like I thought it would be. I think this causes an issue at the point where I have the if(n) statement. In this case n evaluates to true, and so increments size one more than it should.
Furthermore, at this point in my program, the nodes continue to get added correctly, but my insert function continues to return 0x6 as the address, even though they really are in valid locations in memory that I can access.
Can anyone give me any pointers as to what I might be doing wrong?
Your compiler probably should have spotted this, but this line near the end of your helper:
if(n->right) Insert_Helper(v,n->right);
You probably should return whatever Insert_Helper returns:
if(n->right) return Insert_Helper(v,n->right);
You can change if(n) size++ to if (n != NULL) size++