Check if Tree is BST using stack and inorder traversal - c++

Here is my code, but it is not producing any output.
stack < int > st;
bool func(Node * root) {
if (root != NULL) {
func(root -> left);
st.push(root -> data);
func(root -> right);
}
while (!st.empty()) {
int upar = st.top();
st.pop();
if (upar > st.top()) {
continue;
} else {
return 0;
}
}
return 1;
}
Please tell me what am I missing. I traced the code right but it is not showing the relevant result.

What I see from your code is that your function func() is called recursively but its return value is never checked. It should be fine if it means to push stuff into a stack to create an in-order traversal, but you also included the while loop to check if the data are in ascending order. This is the problem.
The easiest fix I can think of is to break it into two:
stack < int > st;
void func(Node * root) {
if (root != NULL) {
func(root -> left);
st.push(root -> data);
func(root -> right);
}
}
bool check(Node* root) {
func(root);
while (!st.empty()) {
int upar = st.top();
st.pop();
if (upar > st.top()) {
continue;
} else {
return 0;
}
}
return 1;
}
but you have to check are you going to assume no duplicate entries in the BST, for you're using upar > st.top() instead of >=.
If you insist to combine the two into one function, you can consider to change func() to pass on upper or lower bound for the values in addition to the Node* so you can correspondingly check the left and right sub-tree. You can skip the use of stack all together in this case. But start with the root node and bound from negative infinity to positive infinity. When you do the recursion, you replace the root->data for upperbound on left tree and for lowerbound on right tree.

Related

How to count number times a given number appears in binary tree?

Could someone please let me know why my code isn't working? I am trying to count the number of times a given value appears in a binary tree using recursion. However, this approach is not working. I'd really appreciate some feedback and insight. Thank you.
public int valCount(int val) {
if (root == null) {
return 0;
}
return valCount(val, *root);
}
public int valCount(int val, Node *root) {
int cnt = 0;
if (root->left != null) {
if (root->data == val) {
cnt++;
}
int leftValCount = valCount(val, root->left);
}
if (root->right != null) {
if (root->data == val) {
cnt++;
}
int rightValCount = valCount(val, root->right);
}
return cnt + leftValCount + rightValCount;
}
A common mistake in recursion is to worry about stack frames other than the current one. Let the recursion do that work for you. Following this rule-of-thumb makes the code much easier to reason about.
The algorithm is simple: for each node, return 1 if the current node matches the target value else 0 if it doesn't and add the results of calling the same function on the left and right subtrees. The base case is when the function is called with a null root, return 0.
int valCount(int val, Node *root) {
if (!root) return 0;
return (root->val == val ? 1 : 0) +
valCount(val, root->left) +
valCount(val, root->right);
}

C++ Binary Search Tree printing and depth calc

I have created binary search tree. My functions can add, delete, and find nodes with numbers. All of that functions is working fine.
Can You help me with two functions:
1) Printing BST
2) Calculating depth of BST?
I have no idea how to do this in a quick and easy way. Depth i calculating during adding new Nodes but I want to have function only for doing that.
class Node{
public:
shared_ptr<Node> right;
shared_ptr<Node> left;
int number;
Node(int number)
{
this->number=number;
right=nullptr;
left=nullptr;
}
~Node()
{
cout<<"Deleted"<<" "<<number<<endl;
}
};
class BT
{
public:
shared_ptr<Node> root;
int deep;
BT(int num)
{
deep=0;
root=make_shared<Node>(num);
}
void add_number(int num)
{
shared_ptr<Node> new_num=make_shared<Node>(num);
shared_ptr<Node> tmp=root;
int tmp_deep=0;
while(tmp!=nullptr)
{
tmp_deep++;
if(tmp->number>num)
{
if (tmp->left==nullptr)
{
tmp->left=new_num;
break;
}
else
tmp=tmp->left;
}
else if (tmp->number<num)
{
if (tmp->right==nullptr)
{
tmp->right=new_num;
break;
}
else
tmp=tmp->right;
}
}
tmp.reset();
if (tmp_deep>deep)
deep=tmp_deep;
}
shared_ptr<Node> find_node(int num)
{
shared_ptr<Node> tmp=root;
while (tmp!=nullptr && tmp->number!=num)
{
if (tmp->number>num)
tmp=tmp->left;
else if (tmp->number<num)
tmp=tmp->right;
}
if (tmp==nullptr)
{
cout<<"Not found";
return nullptr;
}
else
return tmp;
}
void delete_ (int num)
{
shared_ptr<Node> tmp=root;
shared_ptr<Node> previous=root;
while (tmp!=nullptr && tmp->number!=num)
{
if (tmp->number>num)
{
previous=tmp;
tmp=tmp->left;
}
else if (tmp->number<num)
{
previous=tmp;
tmp=tmp->right;
}
}
if (tmp==nullptr)
{
cout<<"Not found";
}
else
{
if(tmp->left==nullptr && tmp->right==nullptr)
{
if (previous->number>tmp->number)
previous->left=nullptr;
else
previous->right=nullptr;
tmp.reset();
}
else if (tmp->left==nullptr && tmp->right!=nullptr)
{
if(tmp->right!=nullptr)
{
previous->right=tmp->right;
}
else
previous->right=tmp->left;
tmp.reset();
}
else if (tmp->left!=nullptr && tmp->right==nullptr)
{
if(tmp->right!=nullptr)
{
previous->left=tmp->right;
}
else
previous->left=tmp->left;
tmp.reset();
}
else if (tmp->left!=nullptr && tmp->right!=nullptr)
{
shared_ptr<Node> tmp_left=tmp->right;
shared_ptr<Node> prev_left=tmp->right;
while (tmp_left->left!=nullptr)
{
//prev_left=tmp_left;
tmp_left=tmp_left->left;
}
if (tmp->number<previous->number)
previous->left=tmp_left;
else
previous->right=tmp_left;
prev_left->left=tmp_left->right;
tmp_left->left=tmp->left;
tmp_left->right=tmp->right;
tmp.reset();
}
}
void show_bt()
{
}
void calc_depth()
{
}
}
};
Both of calculating depth and printing can done using tree traversal. Moreover, tree traversal has O(n) time complexity(n is number of nodes in the tree).
PS: For calculating tree depth you can use one of three traversal methods.
In each recursion call increase the depth variable
After that decrease it and
Save total maximum value(before decreasing it)
This exercise is something every programmer has to do, to learn recursion.
This can also be done by iteration, but that requires to build your stack
For recursion, a function has to be created, which calls itself in order to "calculate" a result.
You have to think, how the end result can be "calculated" from smaller results.
Let's look at the depth calculation.
This is on a tree. Which is constructed from nodes.
So how can we calculate something on the nodes to get the end result?
Every node has a height which is 1 greater than the maximum of height of (the left subtree and, right subtree). If there is no subtree we'll just say it has a height of zero.
BTW: never look for the quick and easy in the beginning. Always the first step is: make it work.

Function to check whether a binary tree is binary search tree or not working

Can someone tell me why is this not working?
This seems correct to me
please someone look into this.
I am not able to find my mistake.
bool checkbst(node* root,int minValue,int maxValue)
{
if(root==NULL)
{
return true;
}
else if(((root->data)>(minValue))&&
((root->data)>(maxValue))&&
(checkbst(root->left,minValue,root->data))&&
(checkbst(root->right,root->data,maxValue)))
{
return true;
}
else
{
return false;
}
}
void isbst(node* root)
{
if( checkbst(root,INT_MIN,INT_MAX))
{
cout<<"the tree is bst";
}
}
You have a typo in checkbst, you are checking
((root->data)>(minValue))&&((root->data)>(maxValue))
while it probably should be
((root->data)>(minValue))&&((root->data)<(maxValue))
(notice the "less than" sign).
Your code verifies that the keys are inside a range, but it does not verify if the children satisfy the bst condition respect to the root. That is, the keys in the left subtree must be lesser than the root and the keys in the right one greater. You should check if the children are not null before doing any comparison involving subtrees.
This version should work:
bool checkbst(node* root, int minValue,int maxValue)
{
if (root == nullptr)
return true;
if (not (root->data >= minValue && root->data <= maxvalue))
return false;
if (root->left)
{
if (root->data < root->left->data)
if (not checkbst(root->left, minValue, maxValue))
return false;
else
return false;
}
// here the left subtree has been checked
if (root->right)
{
if (root->data < root->right->data)
return checkbst(root->right, minValue, maxValue);
else
return false;
}
return true; // everything is ok
}
I have checked your there is a small mistake code but there is a better way to do it. You just have to do the in order traversal of the given tree and store it in a array and then check if the elements in the array are sorted. If the elements are sorted then its a binary search tree else it will be a binary tree (which is a kind of basic difference between a binary tree and binary search tree).
There is a small mistake in your code
((root->data)>(maxValue))
should be
((root->data)<(maxValue))
Here is a solution that is O(n) time complexity and O(1) space. It uses in-order tree traversal to confirm that the tree is sorted according to BST rules, but it does not rely on maintaining an auxiliary array of in-order traversed Nodes. However, because it does rely on recursion it's usage of the stack (i.e. stack depth) can reach O(logn).
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
bool isBSTHelper(Node* root, int& min, int& max)
{
if (nullptr == root)
{
max = numeric_limits<int>::min(); // has meaning for LHS traversal.
min = numeric_limits<int>::max(); // has meaning for RHS traversal.
return true;
}
int lhsMax;
int lhsMin;
if (!isBSTHelper(root->left, lhsMin, lhsMax) ||
lhsMax >= root->data)
{
return false;
}
int rhsMax;
int rhsMin;
if (!isBSTHelper(root->right, rhsMin, rhsMax) ||
rhsMin <= root->data)
{
return false;
}
min = std::min(lhsMin, root->data);
max = std::max(rhsMax, root->data);
return true;
}
bool isBST(Node* root)
{
int min;
int max;
return isBSTHelper(root, min, max);
}

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum

So I tried my own solution in C++ but there is a bug in the code. That problem comes from judge.
So what I'm doing is keep adding a sum value and then check if the provided sum equals to the total sum in a leaf.
bool hasPathSum(TreeNode *root, int sum) {
stack<TreeNode*> st;
TreeNode *temp = root;
int SUM = 0;
bool hasSum = false;
st.push(temp);
while(!st.empty() && temp != NULL)
{
if(temp)
{
st.push(temp);
temp = temp->left;
}
else
{
st.pop();
temp = st.top();
SUM += temp->val;
if(SUM == sum)
hasSum = true;
temp = temp->right;
}
}
return hasSum;
}
Trivial to express recursively:
bool hasPathSum(TreeNode *node, int sum) {
if (!node) {
return sum == 0;
}
return hasPathSum(node->left, sum-node->val) ||
hasPathSum(node->right, sum-node->val);
}
If you translate this to a stack implementation, you will see some of the problems in yours. In particular, it is only at the leaves you want to check the sum (you check interior nodes). You have to adjust the sum as you go up and down the tree (you always add to it).
public static boolean hasPathSum(TreeNode node, int targetSum) {
if (node == null) return false;
targetSum-= node.val;
if (targetSum == 0 && node.left==null && node.right==null) {
return true;
}
int left = hasPathSum(node.left, targetSum);
int right = hasPathSum(node.right, targetSum;
return left || right;
}

BST method returns Segfault

I am writing a method to check if a given tree is a BST using the inorder traversal method. On executing this method, I get a segfault. Can someone help me correct it?
here, maximum stores the largest value in the BST, and k is initialized to 0. The BST is assumed to have unique positive values. isNull(root) checks if the current node is a null node or not.
bool check(BstNode* root)
{
if (root->data==maximum) return true;
isNull(root);
check(root->left);
if (root->data>k)
{
k=root->data;
}
else
{
return false;
}
check(root->right);
}
Every time when you call check(root->left) and check(root->right), I suppose you need to add sth to determine the left and the right branch is null or not. In your code, you just assume that there is sth in left and right branch and call the check function. I think that's the main reason.
You shouldn't need to specify the maximum value. An elegant solution can be found here
There are two approaches you can do this.
One is top-down approach, first check if current node is valid, if so, then check two subtree. This is very intuitive. you can find the code from #lerman's post:
struct TreeNode {
int data;
TreeNode *left;
TreeNode *right;
};
bool isBST(TreeNode *node, int minData, int maxData) {
if(node == NULL) return true;
if(node->data < minData || node->data > maxData) return false;
return isBST(node->left, minData, node->data) && isBST(node->right, node->data, maxData);
}
if(isBST(root, INT_MIN, INT_MAX)) {
puts("This is a BST.");
} else {
puts("This is NOT a BST!");
}
The other way is a bottom-up approach: first check left substree then right substree and check current tree at last. below is the code for this approach.
bool isValidBST(TreeNode *root) {
int mmin, mmax;
return helper(root, mmin, mmax);
}
bool helper(TreeNode* root, int& mmin, int& mmax) {
if(!root) {
mmin = INT_MAX;
mmax = INT_MIN;
return true;
}
int leftmin, leftmax, rightmin, rightmax;
if(!helper(root->left, leftmin, leftmax))
return false;
if(!helper(root->right, rightmin, rightmax))
return false;
if(root->val > leftmax && root->val < rightmin) {
mmin = min(min(leftmin, rightmin), root->val);
mmax = max(max(leftmax, rightmax), root->val);
return true;
}
else
return false;
}
You might notice that the first approach is pre-order traversal and the second approach is post-order traversal. inorder traversal in inappropriate here because it conflicts with the definition of BST.