Binary Tree Structure Balanced , EXC_BAD_ACCESS when using recursion - c++

I am working on question to check if Binary structure tree is balanced or not and when I run the code, I get EXC_BAD_ACCESS and I'm not sure how fix problem and what is causing it to break.
The code is suppose to hit NULL and return (true,-1) at some point and go deep into left subtree. Then return and go to right subtree. We can check whether the subtrees of left and right are balanced by different if it is <= 1. and get its height by max(left,right) +1 for each node.
if <= 1 means not balance returns (false , height) and it bubbles up to recursion.
Thanks
#include <iostream>
using namespace std;
struct TreeNode {
TreeNode * left;
TreeNode * right;
};
class balanceStatusAndHeight{
public:
bool isBalanced;
int height;
balanceStatusAndHeight(bool isBalanced, int height);
};
balanceStatusAndHeight::balanceStatusAndHeight(bool isBalanced, int height) {
this->isBalanced = isBalanced;
this->height = height;
}
balanceStatusAndHeight checkBalance(TreeNode * root) {
if (root == NULL ) {
return balanceStatusAndHeight(true, -1);
}
balanceStatusAndHeight leftResult = checkBalance(root->left);
if ( !leftResult.isBalanced ) {
return leftResult;
}
balanceStatusAndHeight rightResult = checkBalance(root->right);
if ( !rightResult.isBalanced) {
return rightResult;
}
bool subTreesAreBalanced = abs(leftResult.height - rightResult.height) <= 1;
int height = max(leftResult.height, rightResult.height) + 1;
return balanceStatusAndHeight(subTreesAreBalanced, height);
};
int main(int argc, const char * argv[]) {
TreeNode *a = new TreeNode;
a->left = new TreeNode;
a->left->left = new TreeNode;
balanceStatusAndHeight c = checkBalance(a);
cout << c.isBalanced << endl;
return 0;
}

In checkBalance
if (root == NULL )
expects tree branches to be NULL terminated. Unfortunately nothing in the code ensures that the trees are NULL terminated, so this test fails when it hits an uninitialized left or right pointer and then the program tries to access the invalid TreeNode at the uninitialized pointer.
With a modern compiler
struct TreeNode {
TreeNode * left = NULL; // but prefer nullptr to NULL as it has better type safety
TreeNode * right = NULL;
};
solves that problem. Since NULL is being used instead of nullptr the compiler may be old or deliberately set to an older C++ Standard revision and a constructor will be needed instead.
struct TreeNode {
TreeNode * left;
TreeNode * right;
TreeNode():left(NULL), right(NULL)
{
}
};
A smarter constructor or crafty use of aggregate initialization can make your life easier.
Does the program work after this change? No idea. Didn't test for that. It exits without a crash, though.

Related

C++ Return does not work

Adding an element to the AVL tree. Tree currently has no elements. I am trying to add one. Function add performs ok, except program freezes and ends in 2 secs when it comes to return new node(k). Why is that?
struct node
{
int key;
unsigned char height;
node *left;
node *right;
node(int k) {key = k; left = right = 0; height = 1;}
};
node *root;
node *add(node* p, int k)
{
if(!p)
{
return new node(k);
}
if(k < p->key)
p->left = add(p->left,k);
else
p->right = add(p->right,k);
return balance(p);
}
int main()
{
root = NULL;
add(root, 10);
printf("%d",root->key);
return 0;
}
Your function returns a value, and you want to use it. But you're not saving it anywhere. In particular, you seem to be expecting root to contain the new node. So you have to do:
root = add(root, 10);

Segmentation Fault on Pointer null check

I'm getting a segmentation fault on the if (currNode->right) check. Can anyone spot the obvious mistake that I made?
struct node
{
int data;
node* left;
node* right;
};
void Preorder(node *root) {
std::stack<node*> currStack;
currStack.push(root);
while(currStack.top()) {
node *currNode = currStack.top();
currStack.pop();
if (currNode->right) {
currStack.push(currNode->right);
}
if (currNode->left) {
currStack.push(currNode->left);
}
// Print to console
printf("%d ", currNode->data);
}
}
It might be related to my main function, so i'll add it below for reference:
int main() {
node myNode;
myNode.data = 3;
node myNode1;
myNode1.data = 4;
node myNode2;
myNode2.data = 5;
node myNode3;
myNode3.data = 6;
node myNode4;
myNode4.data = 7;
myNode.left = &myNode1;
myNode.right = &myNode2;
myNode1.left = &myNode3;
myNode1.right = &myNode4;
Preorder(&myNode);
return 0;
}
This is due to uninitialized values of left and right pointers in myNode2, myNode3, and myNode4.
Define a constructor for node and you're good:
struct node
{
int data;
node* left;
node* right;
node() : data(0), left(nullptr), right(nullptr) {}
};
currNode seems to be invalid, e.g. NULL. You should check that case before using the pointer in the condition.
This might happen on your top stack node?
Found the Problem: Change the loop condition to while(!currStack.empty()) {}
Actually, I find while(currStack.top()) a pretty strange condition. top() returns a const reference, not a pointer (if you ever expected to get NULL). But if the referenced value is a pointer, and it is NULL, or if we get a reference to, say, int = 0, the loop ends.
Are you sure that's what you wanted? And if there are no elements in the stack, it probably results in an undefined behavior, but it definitely can't return NULL, if you expected that.

C++, Allocate memory, Segmentation fault: 11

#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l, Node *r);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r){
value = N;
left = l;
right = r;
}
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode;
}
}
int main(){
Node *root;
root = nullptr;
insert(root);
cout << root->value << endl;
return 0;
}
This is the beginning of a binary search tree. In the insert function, I am trying to change a nullptr to a pointer pointing to a Node object. When I run this c++ code, I get the error: "Segmentation fault: 11". After doing some research, I believe I need to (re)allocate memory. How can I allocate the memory inside of the insert function, if possible?
First up I presume
if (x == nullptr) {
Is a typo? Didn't you mean
if (x != nullptr) {
??
If it is null you shouldn't be going ahead and dereferencing it.
How you fix the crash really depends on how you want the interface to your BST to be.
You are passing in a nullptr and attempting to assign to it. This wont work. You can't assign to nothing.
So you could do something like.
#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l, Node *r);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r){
value = N;
left = l;
right = r;
}
void insert(Node *x){
if (x != nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode;
}
}
int main(){
Node root(2, nullptr, nullptr);
insert(&root);
cout << root.value << endl;
return 0;
}
Here you have an initial object, allocated on the stack, which you can assign to in insert. If you use this method you are wasting some time doing the initial construction of root in function main, when you are always going to go and assign over it.
If you wanted to persist with heap allocation of the Node. Pass a pointer to pointer to insert e.g.
#include <iostream>
using namespace std;
class Node
{
public:
Node(int N, Node *l = nullptr, Node *r = nullptr);
int value; // stored value
Node *left; // left node
Node *right; // right node
};
Node::Node(int N, Node *l, Node *r)
: value(N), left(l), right(r)
{}
void insert(Node **x)
{
if (x != nullptr)
{
Node* n = new Node(5);
*x = n;
}
}
int main()
{
Node *root = nullptr;
insert(&root);
if(root)
{
cout << root->value << endl;
delete root;
}
return 0;
}
This lets insert manage the allocation of the node.
Have you tried to run valgrind? It's a good idea with these kind of errors (and even if you don't see them), it sometime detects error before the symptoms gets visible (the segmentation fault might be just a consequence of an earlier error - if it's not a normal debugger will stop where the segmentation fault occurs).
It points at the fault directly:
void insert(Node *x){
if (x == nullptr) {
Node newNode(5, nullptr, nullptr);
*x = newNode; <<<--- here
}
}
So you basically check if x is null and if it is you tries to dereference and write to the pointed object? That sounds really bad. You're supposed to do the opposite - check and if it's null you do not dereference the pointer.

Segmentation fault (core dumped) while creating binary tree of given height

This is my first time working with trees. I wrote a c++ code, but it says Segmentation fault (core dumped) , As far as I searched, this error comes from accessing a memory location that may be NULL. I tried 'new' keyword as malloc() should be avoided in c++, But still I didn't get how to resolve this in my code.
# include<iostream>
using namespace std;
struct node
{
int data;
node *left;
node *right;
}*next;
int k=0;
void tree(int i,/*struct*/ node *next = new node)
{
++k; --i;
if (i==0)
return;
//next = new node;
next->data = k*k;
next->left = NULL;
next->right = NULL;
tree(i, next->left);
tree(i, next->right);
return ;
}
void display (node* next)
{
cout<<next->data<<" ";
if (next->left!=NULL)
{
display(next->left);
display(next->right);
}
}
int main()
{
int h;
cout<<"Enter the expected height of tree : ";
cin>>h;
node *root;
root = new node;
root->data=0;
root->left=NULL;
root->right=NULL;
tree(h, (root->left));
tree(h, (root->right));
cout<<root->data<<" ";
display(root->left);
display(root->right);
return 0;
}
There are serious problems with this code. In particular, here:
void display (node* next)
{
cout<<next->data<<" ";
if (next->left!=NULL)
{
...
}
}
You dereference next without ever checking to see whether it's null. And it will be null. That's enough to explain the error you see.
I say that it will be null because of this:
void tree(int i,/*struct*/ node *next = new node)
{
...
return ;
}
...
root->left=NULL;
...
tree(h, (root->left));
...
display(root->left);
The tree function takes its second argument by value-- that means that it does not change the value of root->left. You then call display with a null argument. I suspect that you think void tree(int i,/*struct*/ node *next = new node) means something other than what it actually means.
More fundamentally, you must review the two ways to pass an argument, by reference and by value.
More fundamentally still, you must start with a small, simple program and build up in small steps, rather than trying to write a big complex program all at once.
#include <iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
void tree(int i, struct node **root, int k)
{
if (i < 1)
return;
*root = new struct node;
(*root)->data = k*k;
(*root)->left = NULL;
(*root)->right = NULL;
tree(i - 1, &((*root)->left), k + 1);
tree(i - 1, &((*root)->right), k + 1);
}
void display(struct node *root)
{
if (root == NULL)
return;
cout << root->data << " ";
if (root->left != NULL)
display(root->left);
if (root->right != NULL)
display(root->right);
}
int main()
{
struct node *root;
int h;
cout<<"Enter the expected height of tree : ";
cin>>h;
tree(h, &root, 0);
display(root);
return 0;
}
I think you should do some more read up on how pointers works: http://www.tutorialspoint.com/cprogramming/c_pointers.htm
When you where calling tree(h, root->left) you actually just send the pointers value "NULL" == 0x0. As you want to allocate memory for it you should send a reference to the pointer. Hence &root and &((*root)->left). In the display function you have to check for NULL values both for left and right.
The code above is only improved and doesn't handle any freeing of memory, to be able to do that, traverse the tree and use delete on all leafs and work you back to the root.

How to create a function that returns smallest value of an unordered binary tree

This seems like it should be really easy but I've been having trouble with this for quite some time. As the title says, I'm just trying to find the node in a Binary tree (not a BST!) with the smallest value and return it. I can write a recursive void function pretty easily that can at least assign the smallest value in the function, but I'm getting stuck on how to back track to previous nodes once I reach a NULL pointer.
I have a node class that has a pointer to a left and right child, each with its own value. Here is my (failed) attempt so far:
int preOrder(Node *node, int value, int count, int sizeOfTree)
{
count++; //keeps track of whether or not we have traversed the whole tree
if(value < node->getValue())
value = node->getValue();
if(count == sizeOfTree);
return value;
if(node == NULL)
//Want to return to the previous function call
//How do I do this for a non void function?
//for a void function, you could jsut type "return;" and the function
//back tracks to your previous place in the tree
//but since I'm returning a value, How would I go about doing this?
//these 2 calls are incorrect but the idea is that I first traverse the left subtree
//followed by a traversal of the right subtree.
preOrder(node->getLeft(), value);
preOrder(node->getRight(), value);
}
If possible, I would like to try and do this without keeping track of a "count" as well to make the code cleaner.
Let me know if anymore clarification is needed.
I don't really understand why, in your original code, you need to keep track of the amount of elements traversed. Here is my solution:
int find_min(Node* node)
{
int value = node->getValue()
Node* left_node = node->getLeft();
if (left_node != NULL)
{
int left_value = find_min(left_node);
if (left_value < value)
value = left_value;
}
Node* right_node = node->getRight();
if (right_node != NULL)
{
int right_value = find_min(right_node);
if (right_value < value)
value = right_value;
}
return value;
}
Basically what you need to do is just visit every node and keep track of the smallest value you've seen. This can actually be done fairly simply:
#include <algorithm>
#include <limits>
int preOrder(Node *node)
{
if(node == NULL) return std::numeric_limits<int>::max();
// this should never affect the calculation of the minimum
// (What could possibly be bigger than INT_MAX? At worst it's equal)
int value = std::min(
node->getValue(),
preOrder(node->getLeft())
);
value = std::min(
value,
preOrder(node->getRight())
);
return value;
}
OK, so you have an unordered binary tree and you're trying to find the lowest element in it.
Since the tree is unordered, the lowest element can be at any position in the tree, so you must search the entire tree.
The characteristics of the search will be as follows:
thorough (whole tree is searched)
recursive (rather than iterative, which would be really yucky)
base case: node is NULL
base outcome: maintain current value
Lets write it then:
#include <algorithm>
using namespace std;
int searchLowest(Node * node, int value = INT_MAX)
{
if (node == NULL) // base case
return value; // base outcome
// at this point, node must not be NULL
value = min(value, preOrder(node->getRight(), value)); // thorough, always recurse
value = min(value, preOrder(node->getLeft (), value)); // and check children
value = min(value, node->getValue());
return value;
}
Edit for thoroughness, justice, and OOness:
// Node.h
#include <algorithm>
using namespace std;
template <typename T>
class Node
{
public:
Node(T item)
{
data = item;
}
T lowest()
{
T value = data;
if (right != NULL)
value = min(value, right->lowest());
if (left != NULL)
value = min(value, left->lowest());
return value;
}
Node<T> * getRight()
{
return right;
}
Node<T> * getLeft()
{
return left;
}
private:
T data;
Node<T> * right;
Node<T> * left;
};
// main.cpp
#include <iostream>
#include "Node.h"
using namespace std;
int main(int c, char * v[])
{
Node<int> * tree = sycamore(); // makes a nice big tree
cout << tree->lowest();
}
SEE JIMMY RUN