Reputation: 567
I'm an enthusiast, very new to c++, and I'm working my way through the best way to implement this tree.
I have a number of issues, but primarily I'm trying to figure out the best way of storing a pointer to the parent node, during building of the tree; but I'm getting a Bus Error when I try to access the root->parent->data
value, in preOrder
member function. I can happily access the address root->parent
, this outputs without error.
Could anyone suggest what I'm doing fundamentally wrong here? I'm thinking it might be a scope issue, but there may be a better way of building the tree?
class FibTree {
class Node {
public:
int data;
Node const* left;
Node const* right;
Node const* parent;
Node (void);
};
Node const* root; // 'root' pointer to constant Node
public:
FibTree (int);
Node const* getRoot(void);
void preOrder(Node const* root);
};
// Tree constructor
FibTree::FibTree(int n) {
this->root = buildTree( n );
};
FibTree::Node const* FibTree::getRoot(void) {
return this->root;
}
private:
static Node* buildTree( int n, Node* parent = NULL );
};
void FibTree::preOrder(Node const* root) {
if (root == NULL)
return;
// *** This prints the address of the parent node correctly
cout << root->data << "[" << root->parent << "]" << ",";
// *** This produces a 'Bus Error'
cout << root->data << "[" << root->parent->data << "]" << ",";
preOrder(root->left);
preOrder(root->right);
}
FibTree::Node* FibTree::buildTree( int n, Node* parent ) {
// *** Is there a scope issue with 'thisNode' here?
Node* thisNode = new Node();
thisNode->parent = parent;
if (n < 2) {
thisNode->left = NULL;
thisNode->right = NULL;
thisNode->data = n;
return thisNode;
} else {
thisNode->left = buildTree( n - 1 , thisNode );
thisNode->right = buildTree( n - 2, thisNode );
thisNode->data = thisNode->left->data + thisNode->right->data;
return thisNode;
}
}
// Node constructor
FibTree::Node::Node(void) {
this->data;
this->left;
this->right;
this->parent;
};
int main () {
FibTree f(n);
f.preOrder(f.getRoot());
return 0;
}
Also, would there be a standard approach for avoiding having to pass the root
Node to a traversal function, and have the member function, traverse the created root
node. As I don't feel f.preOrder(f.getRoot())
is very elegant.
Many thanks, Alex
Upvotes: 1
Views: 2532
Reputation: 8886
The problem as far as I can tell is a combination of:
this line in your buildTree
function,
thisNode->parent = parent;
this function,
// Tree constructor
FibTree::FibTree(int n) {
this->root = buildTree( n );
};
and your preOrder
function.
The parent pointer is not being passed in to buildTree in the tree constructor, so the default is a NULL pointer. So root->parent will be NULL (makes sense, since it's the root).
You then call the preOrder
function starting with the root. Root has a parent
that is NULL, but you never check for this (you do check if the root itself is NULL).
You should do something like the following instead:
void FibTree::preOrder(Node const* root) {
if (root == NULL)
return;
if(root->parent == NULL) {
cout << root->data << " [I am the root] " << endl;
}
else {
cout << root->data << "[" << root->parent->data << "]" << ",";
}
preOrder(root->left);
preOrder(root->right);
}
Upvotes: 2
Reputation: 56863
I can't reproduce the problem, but the part that looks most suspicious is this:
// Node constructor
FibTree::Node::Node(void) {
this->data;
this->left;
this->right;
this->parent;
};
the statements (this->data
) do absolutely nothing. Maybe you wanted (and should try):
FibTree::Node::Node()
: data( 0 ),
left( NULL ),
right( NULL ),
parent( NULL )
{
}
To explain: Your code didn't initialize the data and the pointers, so they were uninitialized. If you print the pointer, that usually works but dereferencing it could cause the error you saw.
When you do this, you might see that parent
becomes NULL
and that you need to check for that:
if( root->parent != NULL ) {
cout << root->data << "[" << root->parent->data << "]" << ",";
}
Upvotes: 1