printing the contents of a Binary Search Tree recursively? - c++

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);

Related

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.

why using recursion using while loop goes in infinite loop but works fine with if condition

i am working with inorder ,with recursion, but when i use it with while loop,the last call goes in infinite loop, but works fine with if statement.
can someone help what actually happens with while loop and if statement with recursion
void tree::inorder(node* r)
{
node* temp;
temp = r;
while (temp != NULL)
{
inorder(temp->getleft());
cout << "\n\n\t " << temp->getdata();
inorder(temp->getright());
}
}
Imagine you have a node* head that has a nullptr left node and a nullptr right node.
The code above will get into while (temp != NULL).
It will call inorder(temp->getleft()); on the left node. Because the node is nullptr it, won't get into the while, in the nested call.
It will call inorder(temp->getright()); on the right node. Because the node is nullptr, it won't get into the while, in the nested call.
Then what? It is at the end of the while, but temp is still pointing to your head node. So, it will go back to the beginning of the while. And do that forever.

If/Else statement returns

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.

deleting an item in cicular linked list

My program is supposed to do 3 operations:
Insert
Delete
Show on a circular linked list.
My problem is in the delete function. here is the code:
void c_list::del()
{
int num;
if(isempty())
cout<<"List is Empty!"<<endl;
else
{
node *temp1=first;
node *temp2=NULL;
cout<<"Enter the number that u want to DELETE:"<<endl;
cin>>num;
while(temp1->next!=first && temp1->info != num)
{
temp2=temp1;
temp1=temp1->next;
}
if(num != temp1->info )
cout<<"your number was not found in the list"<<endl;
else
{
if(temp2!=NULL)
{
temp2->next=temp1->next;
cout<<temp1->info<<" was deleted"<<endl;
}
else
{
first=temp1->next;
cout<<temp1->info<<"was deleted"<<endl;
}
}
}
system("pause");
}
Delete function is working in this way: user enters a number, the program searches that number & when it founds the number, removes it from the list.
Now the problem is that, when the user enters a number that does not exist in the list, the "App crash window" appears(I mean this window:Program is not responding), while I have a provided an error message for this case("your number was not found in the list")!!
Can u tell me what the problem is?
Your insert routine is not creating a circular list. When the list is empty and the initial item is inserted first == NULL. In this case your code leaves the list in a non-circular state. Because:
newitem->next=first;
if(first==NULL)
first=newitem;
At this point first->next == NULL, which should never be the case in a circular list. Your search code fails whenever the item to be found does not exist in the list. This is because it never cycles back around to the first node, since the list is not circular.
I think in your while loop you are reaching to the end of list and
after below line temp1 gets NULL.
temp1=temp1->next;
Then you are trying to read info attribute from null pointer and this causes error.
if(num != temp1->info )
I know you said it is circular list but i am not sure it is implemented correctly or not. My suggestion is just try to print temp1->info after while loop to be sure that correctness of list and your implementation.
Happen that, if you insert a number that is not in list, you have a loop in the first while.
So:
node* temp1 = first;
node* temp2 = 0;
while(temp1->next!=first && !temp2) {
if(temp1->info == num) {
/* save pointer and exit from while */
temp2 = temp1;
} else {
temp1 = temp1->next;
}
}
Then your code produce garbage because you never call a delete.
Most likely the problem is on the insert method, where maybe, you don't assign correcly pointers.
And then, why system("pause"); ? Take a look here.

Removing from a Binary Search Tree

I am trying to write a remove from a binary tree function. I'm kinda lost so I'm trying to handle it case by case, starting with if the value I'm trying to remove is in the root of the BST. To test my function, I am first calling a printcontents() function that prints all the contents of the tree, then I'm calling remove(8) [8 being the value in my root at the moment), and then calling printcontents() again. The way I'm doing it is by trying to replace the root with the "right-most" value in the left side of the tree. When I call printcontents the second time, it prints the new root value correctly, but when it continues printing the contents and reaches the point where that value used to be, it has a random long number "-572......"(although i don't think the number matters) and then my program crashes. I see my root's value is being replaced, but what happens afterwards??
Here's my remove function:
void BinarySearchTree::remove(int value) {
Node* tmp = head;
Node* tmp2 = head;
if (head->data == value && head->left != NULL) {
tmp=tmp->left;
while (tmp->right != NULL) {
tmp=tmp->right;
}
while (tmp2->right->right != NULL) {
tmp2=tmp2->right;
}
if (tmp->left == NULL) {
head->data = tmp->data;
tmp2->right = NULL;
delete tmp;
}
if (tmp->left != NULL) {
head->data = tmp->data;
tmp2->right = tmp->left;
delete tmp;
}
}
It's obviously incomplete, but I'm testing it to only handle the case in which the root is removed and replaced by the right-most value in the left side of the tree (assuming there is a left side, which there is), and I feel like logically it should be working, so perhaps it is when I "delete tmp" that things go wrong. I don't know whether posting my whole program will be necessary, but if so, let me know!
May I suggest that instead of writing out for root, why don't you treat the case as it is dealt with in CLRS : That is two distinct cases.
1. When node to be deleted is a leaf
2. When node to be deleted is non-leaf(in that case replace it with inorder successor/predecessor).
The root deletion obviously falls under the second case. This is just a suggestion.