i wrote this code to check how many nodes has only left son
template <class T>
int Tree<T>::onlyLeftSon(Node<T> * current) //check how many left son there are on trehh
{
if (current == NULL) //empty tree or we finish the tree
return 0;
return ( onlyLeftSon(current->left) + onlyLeftSon(current->right) ); // return the sum from left and right
if (!current->left && !current->right) //if this node not have sons
return 0;
if (current->left && !current->right) //if this node not has only left son
return 1;
}
this return 0
why?
The unconditional statement:
return ( onlyLeftSon(current->left) + onlyLeftSon(current->right) );
Always happens after the current == NULL check fails. This means that you will always calculate onlyLeftSon as the sum of the two child nodes in all cases, except for the current == NULL case where you return 0. 0 + 0 will always be zero.
What you likely want is:
template <class T>
int Tree<T>::onlyLeftSon(Node<T> * current)
{
if (current == NULL) //empty tree or we finish the tree
return 0;
if (!current->left && !current->right) //if this node not have sons
return 0;
if (current->left && !current->right) //if this node not has only left son
return 1;
return ( onlyLeftSon(current->left) + onlyLeftSon(current->right) );
}
At that point, the algorithm seems to be calculating the number of leafs in a tree whose parent only has a left-leaf. This is different from counting the number of left leafs, or left-child nodes in general:
a
/ \
b c
The tree above will return onlyLeftSon(tree) == 0. Why?
When current == a, we have:
current != NULL, current->left != NULL, and current->right != NULL.
Therefore, non of the if statements succeed and we recurse to b and c.
Both b and c return 0, because they are both childless.
Is that what you are trying to do? Or are you trying to calculate every left leaf in general?
Related
I have written a function that returns true if given binary tree is binary search tree else returns false.
bool IsBst(node* root)
{
if(root->left == NULL && root->right == NULL)
{
return true;
}
if(root->left->data <= root->data && root->right->data > root->data)
{
return (IsBst(root->left) && IsBst(root->right))
}
else
{
else false;
}
}
Is my function right?
Will this function return right answer?
I have doubt in case of if left child is null then what will this comparison root->left->data<=root->data return?(If there is NULL)
Help me to improve this!
Thanks in advance!
It should be something like
bool IsBst(const node* root, node* minNode = nullptr, node* maxNode = nullptr)
{
if (root == nullptr) {
return true;
}
if (minNode != nullptr && root->data < minNode->data)
{
return false;
}
if (maxNode != nullptr && maxNode->data < root->data)
{
return false;
}
return IsBst(root->left, minNode, root)
&& IsBst(root->right, root, maxNode);
}
If you're using C++ 17 and above, you can do it even more elegantly by using an optional class. Hence, you don't need to do nullptr checks for min and max:
bool checkBST0(const Node* root, const std::optional<int>& min, const std::optional<int>& max) {
if (root != nullptr) {
const auto data = root->data;
if ((min.has_value() && min >= data) ||
(max.has_value() && max <= data)) {
return false;
}
std::optional<int> opt(data);
return checkBST0(root->left, min, opt) && checkBST0(root->right, opt, max);
}
return true;
}
Initially, you should call this method with an optional without any value:
std::optional<int> emptyOptional;
return checkBST0(root, emptyOptional, emptyOptional);
Nope, it's not right. It would fail on this tree:
3
\
\
5
And it would give a wrong answer on this one:
4
/ \
/ \
/ \
2 6
/ \ / \
1 9 0 8
A BST is defined as a tree, whose each internal node stores a key greater than all the keys in the node’s left subtree and less than those in its right subtree (see the Wikipedia article).
So it's not enough for a 1-2-9 left subtree in my example to have a left node value less than it's root (1<2) and the right node greater than it (9>2). It should also satisfy the condition that all its nodes have values less than 4, the value in the whole tree's root.
Here is an example in C I gave in the answer to the question Pseudo code to check if binary tree is a binary search tree - not sure about the recursion:
// Test a node against its closest left-side and right-side ancestors
boolean isNodeBST(NODE *lt, NODE *node, NODE *rt)
{
if(node == NULL)
return true;
if(lt != NULL && node->key <= lt->key)
return false;
if(rt != NULL && node->key >= rt->key)
return false;
return
isNodeBST(lt, node->left, node) &&
isNodeBST(node, node->right, rt);
}
boolean isTreeBST(TREE *tree)
{
return isNodeBST( NULL, tree->root, NULL);
}
My assignment is to find the sum of all nodes on each branch in a binary search tree using recursion, and compare them to a user input value. If the user input value matches a sum of one of the branches, the function should return true.
In other words, the sum of 32+24+21+14=91. The sum of 32+24+28+25=109. The sum of 32+24+28+31=115 etc. I have tried many different methods, but cant seem to figure out how to traverse each branch accurately. So far I have only been able to traverse and find the sum of the left-most branch.
I am using the method of subtracting each node from the user input value. If the value reaches 0 at a Leaf-node, then clearly the user-input matches the node-sum of that branch on the tree.
The particular points of difficulty for me are when the branch diverges, such as at the node [24] and [28]. I clearly am getting something very simple wrong, but I cant figure it out.
Below is the condensed code I've written so far, in the form of two companion methods (also required for the assignment).
public:
bool findBranchSum1(int value) throw (InvalidTreeArgument) {
if (root == nullptr)
throw InvalidTreeArgument();
return(findBranchSum(root, value));
}
private:
bool findBranchSum(NodePtr node, int value) throw (InvalidTreeArgument)
{
bool result = false;
if (root == nullptr)
throw InvalidTreeArgument();
value -= node->getElement(); //subtract current node from user-input value.
cout << "Current Value = " << value << endl; //help track value changes
if (node->getLeftSide() == nullptr && node->getRightSide() == nullptr)
{
if (value == 0)
{
result = true;
return(true);
}
else
return(false);
}
else
{
if (node->getLeftSide() != nullptr)
{
node = node->getLeftSide(); //advance to next Left node
result = findBranchSum(node, value); //recursive call using new node
}
if (node->getRightSide() != nullptr)
{
node = node->getRightSide(); //advance to next Right node
result = findBranchSum(node, value); //recursive call using new node
}
return(result);
}
}
What am I doing wrong, and how can I fix my code to find the sum of each branch on the tree? Thank you in advance. I apologize for any errors in my format, or missing information.
This is wrong:
if (node->getLeftSide() != nullptr)
{
node = node->getLeftSide(); //advance to next Left node
result = findBranchSum(node, value); //recursive call using new node
}
if (node->getRightSide() != nullptr)
{
node = node->getRightSide(); //advance to next Right node
result = findBranchSum(node, value); //recursive call using new node
}
because you move to the left and then to the right branch of the left (node is changed by your assignment), if it exists! Change to:
if (node->getLeftSide() != nullptr)
{
result = findBranchSum(node->getLeftSide(), value);
}
if (node->getRightSide() != nullptr)
{
result = findBranchSum(node->getRightSide(), value);
}
Your return value management is also broken, change it to:
if (node->getLeftSide() != nullptr)
{
result = findBranchSum(node->getLeftSide(), value);
}
if (!result && node->getRightSide() != nullptr) // cut exploration if previous was correct...
{
result = findBranchSum(node->getRightSide(), value);
}
return result;
if you need to stop at the first correct branch.
I might try something like the following.
bool IsLeaf(Node const * node) {
return node && !node->left && !node->right;
}
bool CheckPathSum(Node const * node, int const target, int const sum_so_far) {
if (!node) return false;
int const sum = sum_so_far + node->element;
if IsLeaf(node) && (sum == target) return true;
return CheckPathSum(node->left, target, sum) ||
CheckPathSum(node->right, target, sum);
}
Call as
CheckPathSum(root, target, 0);
In Java, i tried this-
private static void branchSumsUtil(TreeNode root, List<Integer> sumArray, int runningSum) {
if (root == null){
return;
}
int newRunningSum = runningSum + root.key;
if (root.left == null && root.right == null){
sumArray.add(newRunningSum);
}
branchSumsUtil(root.left, sumArray, newRunningSum);
branchSumsUtil(root.right, sumArray, newRunningSum);
}
I'm trying to make a function that tells if a Tree is "complete" or not, so basically if every subtree ends with two leaves and has no void subtrees. But when I run the code I get the following error:
[main] C:\Users\GIT\Desktop\dev\a.exe 1000 (0) handle_exceptions: Exception: STA
TUS_ACCESS_VIOLATION
[main] a 1000 (0) handle_exceptions: Dumping stack trace to a.exe.core
what should I do to solve this? Here's the code:
struct Tree {
int n;
Tree *left,*right;
Tree(): left(NULL),right(NULL) {}
};
bool isFoglia(Tree* root) {
return root->right == NULL && root->left == NULL;
}
bool isMinimum(Tree* root) {
return isFoglia(root->right) && isFoglia(root->left);
}
bool isCompleto(Tree* root) {
if(root == NULL || isFoglia(root) || isMinimum(root)) return 1;
if(isFoglia(root->right) && root->left == NULL) return 0;
if(isFoglia(root->left) && root->right == NULL) return 0;
return isCompleto(root->right) && isCompleto(root->left);
}
EDIT: I have the same error when I try to run this function that tells the maximum sum of a tree that you can get summing its elements from the top to the bottom, choosing each time which subtree to go:
int maxSum(Tree *root) {// max is an int function that returns the a if a>=b or b if b>a
if(isMinimum(root)) {
return max(root->n+root->right->n,root->n+root->left->n);
}
else {
return max(root->n+maxSum(root->right),root->n+maxSum(root->left));
}
}
Consider, for example, a tree that is severely unbalanced to the point that it is a linked list, i.e.
o
/ \
/ NULL
o
/ \
/ NULL
o
/ \
NULL NULL
And run this on the root node.
Then:
// root is not NULL, isFoglia(root) is not true, so we descend into
// isMinimum(root)
if(root == NULL || isFoglia(root) || isMinimum(root)) return 1;
whereupon in isMinimum(root),
return isFoglia(root->right) && isFoglia(root->left);
descends into isFoglia(root->right), which is isFoglia(nullptr), where finally
return root->right == NULL && root->left == NULL;
tries to take the left and right members of a null pointer.
In fact, this happens for any node that has a left child but not a right one, and further down,
if(isFoglia(root->left) && root->right == NULL) return 0;
exhibits the same problem for nodes that have a right child but not a left one. A simple fix would be to make isFoglia safely callable on null pointers, such as
bool isFoglia(Tree* root) {
return root != NULL && (root->right == NULL && root->left == NULL);
}
I'm getting a segmentation fault with my code and I'm not sure why. I'm trying to find the max value in a regular binary tree that is not ordered.
tnode<int> *maxT(tnode<int> *t)
{
if (t == NULL) return NULL;
tnode<int> *left = maxT(t->left);
tnode<int> *right = maxT(t->right);
if (left->nodeValue > right->nodeValue)
{
return maxT(left);
}
if (left->nodeValue < right->nodeValue)
{
return maxT(right);
}
}
The fundamentals of the algorithm are fairly straight forward. Because the tree is unordered, all nodes must be visited, with the following preconditions:
A null node pointer results in null as an answer.
Else a node with no children results in the current node
Else result is the max of the node compared to the max of its children.
Given that, I'm pretty sure this is what you're trying to do:
template<typename T>
tnode<T>* maxT(const tnode<T>* t)
{
if (!t)
return nullptr;
tnode<T>* lmax = maxT(t->left);
tnode<T>* rmax = maxT(t->right);
tnode<T>* cmax = (lmax && rmax)
? ((rmax->nodeValue < lmax->nodeValue ? lmax : rmax))
: (lmax ? lmax : rmax);
return (!cmax || (cmax->nodeValue < t->nodeValue) ? t : cmax);
}
tnode<int> *maxT(tnode<int> *t)
{
if (t->right == NULL && t->left == NULL) //leaf node
return t->nodeValue;
else if (t->right == NULL) //no right subtree
return MAX(t->nodeValue, maxT(t->left))
else if (t->left == NULL) //no left subtree
return MAX(t->nodeValue, maxT(t->right))
else
return MAX(maxT(t->right), maxT(t->left));
}
In your case, what happens if a node doesn't have a right or left child. Then either node->right == NULL or node->left == NULL. Yet you are trying to access left->nodeValue or right->nodeValue.
Let's say we are given the function definition
bool sameValsOrder(node *p , node *q)
We have to write a function to compare the 2 linked list if they have the same order it returns true else false
[77777] and [77] -> true
[1234567] and [1234555567] -> true
bool sameValsOrder (node *p , node *q)
{
if ( q==NULL && p==NULL)
return true;
else if ((q=NULL && p != NULL)|| (p=NULL && q!= NULL))
return false;
else if ( q != NULL && p != NULL)
while ( q != 0 && p != 0)
{
if (p->data != q->data)
{
return false;
break;
}
else
{
p= p-> next ;
q= q-> next;
}
}
return true;
}
The above code is my answer but I realized something. Do I need to add more if statement inside the while loop such that a link list of [77777] and [7] should return true since its the same order just less.
According to what you have written you don't actually care about the values but you want to return true if the list is ordered? It seems like you just need to go through each value in the list. As long as the NEXT value is NOT LESS than the PREVIOUS value keep going through the list. If you reach the end, then return true because the list is in order. If, at any point you come across a value that is less than any previous value then just return false right there.
#include <iostream>
using namespace std;
class node{
public:
node(){next = NULL;}
int data;
node * next;
};
class myList{
public:
myList(){pRoot = NULL;}
void add(int data);
node * pRoot;
};
bool sameValsOrder (node *p , node *q)
{
if ( q==NULL && p==NULL) // If both lists are empty
return true;
else if ((q==NULL && p != NULL)|| (p==NULL && q!= NULL)) // One list is empty and the other is not
return false;
else if ( q != NULL && p != NULL) //Both lists contain values we must check
{
int temp; //I am going to assume a singly linked list (no access to previous value), need this to hold previous value
temp = p->data;
while (p->next != NULL) //The list still contains elements
{
if (p->next->data < temp) //The value in the current node is LESS than our temp, then list is out of order so return false
return false;
else { //Otherwise move to the next node
temp = p->data;
p = p->next;
}
}
temp = q->data; //Reset temp for q
//Do the same thing for q
while (q->next != NULL) //The list still contains elements
{
if (q->next->data < temp) //The value in the current node is LESS than our temp, then list is out of order so return false
return false;
else { //Otherwise move to the next node
temp = q->data;
q = q->next;
}
}
}
return true; //If we are this are then both lists should be ordered
}
int main()
{
myList * p = new myList();
myList * q = new myList();
p->add(7);
p->add(6);
p->add(5);
p->add(4);
p->add(3);
p->add(2);
p->add(1);
q->add(7);
q->add(6);
q->add(5);
q->add(5);
q->add(5);
q->add(5);
q->add(4);
q->add(3);
q->add(2);
q->add(1);
cout << sameValsOrder (p->pRoot, q->pRoot) << endl;
return 0;
}
void myList::add(int data)
{
node * nodeToAdd = new node();
nodeToAdd->data = data;
if(pRoot == NULL) //List is empty
{
pRoot = nodeToAdd;
pRoot->next = NULL;
}
else //List not empty insert new node at beginning
{
nodeToAdd->next = pRoot;
pRoot = nodeToAdd;
}
}
while ( q != 0 && p != 0)
{
if (p->data != q->data)
return false;
break;
else
p= p-> next ;
q= q-> next;
}
this is wrong you are returning false when it is not same but as the size of p and q can be different
[1112] [12] will return false which it shouldnt
while(q!=NULL || p!=NULL)
{
if(q->data==p->data)
{
p=p->next;
break;
}
else(q->data < p->data)
q=q->next;
}
Basically you should move forward in the first linked list only when the values don't match other wise traverse the second list till it matches.
The OP has indicated in comments that he wants to consider 'runs' of nodes with the same data as being matched even if those runs have a difference length in the 2 lists. That simplifies to when (q->data == p->data) then skip nodes that comprise a run.
Here's some pseudocode; a C implementation is really not any more complex (though it might be several more lines):
bool sameValsOrder (node *p , node *q)
{
while not at the end of either list, and the current nodes are the same {
skip run in q, taking care to deal with the NULL at the end of the list
skip run in p, taking care to deal with the NULL at the end of the list
}
if we've reached the end of both lists, they are equivalent
}
C Implementation:
bool sameValsOrder (node *p , node *q)
{
while (q && p && (q->data == p->data)) {
/* find next different node in each list (ie., skip runs) */
int tmp = q->data; /* or whatever type `data` is */
while (q && (q->data == tmp)) {
q = q->next;
}
while (p && (p->data == tmp)) {
p = p->next;
}
}
/*
* we've either reached the end of one or both lists,
* or have found a `data` difference
*/
if (p == q) {
/* should happen only when `q` and `p` are NULL */
assert(q == NULL);
assert(p == NULL);
/* we've reached the end of both lists, so they're 'equivalent' */
return true;
}
return false;
}