void insert(int ) method for BST tree/C++ - c++

I have been trying to get this function working for the longest time now. It is part of an assignment for an online course, but it seems no matter what I submit, the function fails for both the empty child test and the left child test. See code below. The main() function is deliberately commented out. Any info./input is much appreciated.
// C++ binary trees and stuff;
//
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
class BST
{
public:
int data;
BST *left;
BST *right;
//BST *root;
// BST() constructor
BST (int num)
{
data = num;
left = nullptr;
right = nullptr;
root = nullptr;
}
// constructors for root node(s), initializing as root when no values exist yet;
BST() : root (nullptr){}
BST (BST *rootNode) : root(rootNode){}
void insert (int value)
{
BST *newNode = new BST();
newNode = root;
if (root == nullptr)
{
root = new BST (value);
}
else
{
root->data = value;
}
// check if newNode's value equals the passed-in value:
if (value == root->data)
{
//cout << "\nWarning! Value already exists in tree, so nothing will be done.\n";
return;
}
// check if value is < or > newNode's value:
if (value <= root->data)
{
if (root->left == nullptr)
{
// make a new node as the left child of this node,
root->left = new BST(value);
}
else
{
// recursively call insert() on tree's left side,
root->left->insert(value);
}
}
else
{
if (root->right == nullptr)
{
// make a new node as the right child of this node,
root->right = new BST(value);
}
else
{
// recursively call insert() on tree's right side,
root->right->insert(value);
}
}
}
public:
BST *root;
};
/*
int main (int argc, char *argv[])
{
//...insert code here,
// create nodes,...
BST rootNode(5);
BST leftNode(4);
BST rightNode(6);
// connect the nodes to the tree via rootNode.left and rootNode.right,..
rootNode.left = &leftNode;
rootNode.right = &rightNode;
printf ("\nData (root) value = %i, rootNode.left = %i, and rootNode.right = %i\n",
rootNode.data, rootNode.left->data, rootNode.right->data);
cout << "\n\nHello, Solar System!\n";
return 0;
}
*/

Okay, here's my suggestion. You need to reformat your code. You need two classes. You need a BST, and you need a Node. The various methods to add/remove/traverse are part of the BST class. Nodes are just Nodes.
So:
class BST_Node {
public:
int value;
BST_Node * left = nullptr;
BST_Node * right = nullptr;
// Define constructors, etc.
};
class BST {
public:
BST_Node * root = nullptr;
BST_Node * insert(int value);
void insertNode(BST_Node *node);
void insertNodeBelow(BST_Node *nodeToInsert, BST_Node *startingNode);
};
BST_Node * BST::insert(int value) {
BST_Node * node = new BST_Node(value);
insertNode(node);
return node;
}
void BST::insertNode(BST_Node *node) {
if (node == nullptr) {
return;
}
if (root == nullptr) {
root = node;
}
else {
insertNodeBelow(node, root);
}
}
void BST::insertNodeBelow(BST_Node *node, BST_Node *startingNode) {
if (node == nullptr || startingNode == nullptr) {
return;
}
if (node->value < startingNode->value) {
if (startingNode->left != nullptr) {
insertNodeBelow(node, startingNode->left);
}
else {
startingNode->left = node;
}
}
else {
if (startingNode->right != nullptr) {
insertNodeBelow(node, startingNode->right);
}
else {
startingNode->right = node;
}
}
}
How this works... First, the logic of how to store nodes is in BST. Nodes don't care. Second, I made methods for either inserting a value or a node. Because I think that's handy. That should be fairly easy to understand.
The root node can be null, if so, then your inserted node is now root. Otherwise it calls the recursive insertion function. Now, you could simplify this a little, but I didn't want to get too clever.
So it's simple. We look to see where it belongs relative to the point we're at (initially the root). Either we go into the left branch or the right branch. But that branch could be empty, so you just plop it right in. If it's not empty, then you recurse.
I didn't test it.

Related

Implementation of BST C++ Segmentation Fault

I have implemented binary search tree in C++ and for some reason I am not seeing where the segmentation fault occurs. But I do notice that when I comment out root = node in the first conditional statement in addNode the error goes away. What exactly is a segmentation fault and how does it related to pointers?
#include <iostream>
#include <iomanip>
using namespace std;
class bstNode
{
public:
int value;
bstNode *left;
bstNode *right;
bstNode(){};
~bstNode(){};
bstNode(int value)
{
this->value = value;
this->left = NULL;
this->right = NULL;
}
bstNode(int value, bstNode *left, bstNode *right)
{
this->value = value;
this->left = left;
this->right = right;
}
bstNode *root;
void addNode(int value)
{
if (root == NULL)
{
bstNode *node = new bstNode(value);
root = node;
}
else
{
bstNode *focusNode = root;
bstNode *parent;
while (focusNode != NULL)
{
if (value > focusNode->value)
{
focusNode = focusNode->right;
if (focusNode == NULL)
{
focusNode->right = new bstNode(value);
}
}
else
{
focusNode = focusNode->left;
if (focusNode == NULL)
{
focusNode->left = new bstNode(value);
}
}
}
}
}
static void printBST(bstNode *node)
{
while (node != NULL)
{
printBST(node->left);
cout << node->value;
printBST(node->right);
}
}
};
int main()
{
bstNode *node = new bstNode();
node->addNode(7);
node->addNode(2);
node->addNode(18);
node->addNode(6);
node->addNode(4);
node->addNode(23);
bstNode::printBST(node->root);
return 0;
}
The immediate error is this
if (focusNode == NULL) {
focusNode->left = new bstNode(value);
}
this is clearly wrong, if a pointer is null you cannot use it. You have this in multiple places. Fix that and then update the question once you have got past that. How did I know this? I ran your code under my debugger and it told me immediatley, you should learn how to get the most out of your debugger.
Next
void addNode(int value)
as a method for a class defined as
class bstNode {
public:
int value;
is very bad practice. In that method what does value refer to? The argument or the member variable. Get into the habit of giving member variables specific names like this
class bstNode {
public:
int value_;
Also minor nits. The accepted style for naming classes is with leading Caps like this
class BstNode {
public:
int value_;
or even
class BSTNode
class bstNode {
public:
int value_;
using namespace std;
I'd advise against doing this in general. It's hard to be sure what's in namespace std, but the short summary is "a lot, and more all the time", so making all of it visible directly can lead to problems.
bstNode(){};
~bstNode(){};
These don't really accomplish anything useful. The point of a constructor is to initialize the object, but these just leave the object uninitialized, which can lead to problems--especially segmentation faults when/if you try to dereference an uninitialized pointer.
bstNode(int value){
this->value = value;
this->left = NULL;
this->right = NULL;
}
This is better, but I'd prefer to use a member initializer list instead of assignments inside the body of the ctor, and I'd prefer nullptr over NULL:
bstNode(int value)
: value(value)
, left(nullptr)
, right(nullptr) {}
This next one:
bstNode(int value, bstNode* left, bstNode* right){
this->value = value;
this->left = left;
this->right = right;
}
...is pretty nicely written (though it could also use a member initializer list, which is usually preferable), but only rarely useful when building a binary search tree, because in normal use you only ever insert new leaf nodes, not new internal nodes.
void addNode(int value){
if (root == NULL){
bstNode* node = new bstNode(value);
root = node;
}
else{
bstNode* focusNode = root;
bstNode* parent;
while(focusNode != NULL){
if(value > focusNode->value){
focusNode = focusNode->right;
if(focusNode == NULL){
focusNode->right = new bstNode(value);
}
}
else{
focusNode = focusNode->left;
if(focusNode == NULL){
focusNode->left = new bstNode(value);
}
}
}
}
}
This is at least one obvious source of a segmentation fault--you dereference a pointer immediately after verifying that it's null.
At least for a first attempt, I think I'd use a recursive implementation, which tends to be simpler:
void addNode(int value, bstNode *&node = root) {
if (node == nullptr) {
node = new node(value);
} else if (value < node->value) {
addNode(value, node->left);
} else if (value > node->value) {
addNode(value, node->right);
} else {
// attempt at inserting duplicate value
}
}
Note that this passes a reference to a pointer, so we can modify the "current" pointer, rather than having to track the parent pointer while traversing the tree.
static void printBST(bstNode* node){
while(node != NULL){
printBST(node->left);
cout << node->value;
printBST(node->right);
}
}
Since we're doing this recursively, we don't need (or even want) a loop. Traversing the left sub-tree, the current node, and the right subtree traverses the entire tree, with no iteration needed.
Also note that this doesn't print any delimiter between the numbers in the nodes, so a tree containing 12, 34 and a tree containing 1, 2, 3, 4 will both be printed out as 1234, which probably isn't very useful. Fortunately, adding a delimiter is pretty easy.
static void printBST(bstNode* node){
if (node != nullptr){
printBST(node->left);
cout << node->value << ' ';
printBST(node->right);
}
}
In the the following code...
while(focusNode != NULL){
if(value > focusNode->value){
focusNode = focusNode->right;
if(focusNode == NULL){
focusNode->right = new bstNode(value);
}
}
else{
focusNode = focusNode->left;
if(focusNode == NULL){
focusNode->left = new bstNode(value);
}
}
}
...you are referencing the children of a node that is guaranteed to be NULL because you verified that using the conditional statement. Since the node itself does not exist, it doesn't have properties like children. Imagine you're trying to communicate with the child of a person who has never existed.
The variable focusNode stores an address of a node. What focusNode->value does is that it goes to the node whose address focusNode stores and retrieves the value property from there.
When focusNode is NULL, it doesn't point to any node, thus you can't go there and retrieve its value property.
I wrote the code that you can replace with your while loop. I have tested it and it works:
while(true){
if(value > focusNode->value){
if(focusNode->right == NULL){
focusNode->right = new bstNode(value);
return;
} else focusNode = focusNode->right;
}
else{
if(focusNode->left == NULL){
focusNode->left = new bstNode(value);
return;
} else focusNode = focusNode->left;
}
}
I also fixed your printBST function. In the printBST function use if instead of while, because the the code inside the while loop would be executed an infinite number of times instead of printing the BST once.
static void printBST(bstNode* node){
if(node != NULL){
printBST(node->left);
cout << node->value <<" ";
printBST(node->right);
}
}

I wanted to implement a BST and tried using vector for input

I wanted to implement a BST class with a vector and somehow its not working. I just wanted to know the reason why its not working.
The main reason that I can think of that root in the BST always remain NULL.
I wanted to experiment ways to use classes in data structures.
#include<iostream>
#include<vector>
using namespace std;
class Node{
public:
int data;
Node* left ;
Node* right ;
Node(int val){
data = val;
left = NULL;
right = NULL;
}
};
class BST{
public:
Node* root = NULL;
void insert(Node* r,int data){
Node* new_node = new Node(data);
if(r == NULL){
r = new_node;
}
if(data < r->data){
if(r->left == NULL){
r->left = new_node;
}
else{
insert(r->left,data);
}
}else if(data > r->data){
if(r->right == NULL){
r->right = new_node;
}
else{
insert(r->right,data);
}
}else{
return;
}
return;
}
BST(vector<int> bst_array){
for(int i = 0; i<bst_array.size(); i++){
insert(root,bst_array[i]);
}
}
void print_t(Node* r){
if(r == NULL){
cout<<"NULL";
return;
}
else{
print_t(r->left);
cout<<r->data<<" ";
print_t(r->right);
}
}
};
int main(){
vector<int> v = {1,3,5,44,23,78,21};
BST* tr = new BST(v);
tr->print_t(tr->root);
return 0;
}
There seem to be a logical mistake on my end please help me find it.
Thanks in advance.
The reason is that root is never assigned another value after its initialisation to NULL. Passing root as argument to the insert method can never alter root itself, as it is not the address of root that is passed, but its value.
Some other remarks:
insert always starts by creating a new node, at every step of the recursion. This is a waste of node creation. In the end you just need one new node, so only create it when its position in the tree has been identified.
The final else is not needed, as all it does is execute a return, which it would have done anyway without that else block
As insert is a method of BST, it is a pity that it requires a node as argument. You would really like to just do insert(data) and let it take care of it. For that to happen I suggest to move your insert method to the Node class, where the this node takes over the role of the argument. Then the BST class could get a wrapping insert method that forwards the job to the other insert method.
Instead of NULL use nullptr.
To solve the main issue, there are many solutions possible. But after making the above changes, it is quite easy to assign to root in the simplified insert method on the BST class.
Here is how it could work:
class Node{
public:
int data;
Node* left ;
Node* right ;
Node(int val){
data = val;
left = nullptr;
right = nullptr;
}
void insert(int data) {
if (data < this->data) {
if (this->left == nullptr) {
this->left = new Node(data);
} else {
this->left->insert(data);
}
} else if (data > this->data) {
if (this->right == nullptr) {
this->right = new Node(data);
} else {
this->right->insert(data);
}
}
}
};
class BST {
public:
Node* root = nullptr;
void insert(int data) {
if (root == NULL) { // Assign to root
root = new Node(data);
} else { // Defer the task to the Node class
root->insert(data);
}
}
BST(vector<int> bst_array){
for(int i = 0; i<bst_array.size(); i++){
insert(bst_array[i]); // No node argument
}
}
/* ...other methods ...*/
}

Binary Search Tree Problem with Insert Function

Hello i am new to c++ and learning about binary search trees.
I am trying to implement a simple binary search tree where i can store "KeyCodePair" object(which has string and integer) and doing some operations on tree like search and insert. Seems like there are some problems with my logic thats why first Insert function is working but second is not working(calling them from Main) I guess there is problem with the way i implemented "root" where should i write it
This is Tree.cpp:
#include "Tree.h";
#include "KeyCodePair.h";
Tree::Tree() {
treeNode* root = NULL;
}
Tree::treeNode* Tree::getNewNode(KeyCodePair data) {
treeNode* newNode = new treeNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
Tree::treeNode* Tree::Insert(KeyCodePair data) {
if (root == NULL) {
root = getNewNode(data);
}
else if (data.getCode() <= root->data.getCode()) {
root->left = Insert(data);
}
else {
root->right = Insert(data);
}
return root;
}
bool Tree::Search(KeyCodePair data) {
if (root == NULL) {
return false;
}
else if (root->data.getCode() == data.getCode()) {
return true;
}
else if (data.getCode() <= root->data.getCode()) {
return Search(data);
}
else {
return Search(data);
}
}
Tree.h:
#ifndef TREE_H
#define TREE_H
#include "KeyCodePair.h"
class Tree {
private:
struct treeNode {
KeyCodePair data;
treeNode* left;
treeNode* right;
} ;
treeNode* root;
public:
treeNode* Insert( KeyCodePair data);
bool Search(KeyCodePair data);
treeNode* getNewNode(KeyCodePair data);
Tree();
};
#endif
KeyCodePair.cpp
#include "KeyCodePair.h"
KeyCodePair::KeyCodePair(string keyparam, int codeparam) {
key = keyparam;
code = codeparam;
}
KeyCodePair::KeyCodePair() {
}
string KeyCodePair::getKey() {
return key;
}
int KeyCodePair::getCode() {
return code;
}
KeyCodePair.h
#ifndef KEYCODEPAIR_H
#define KEYCODEPAIR_H
#include <iostream>
using namespace std;
class KeyCodePair {
private:
string key;
int code;
public:
KeyCodePair();
KeyCodePair(string key, int code);
string getKey();
int getCode();
};
#endif
And Finally this is the main:
#include <iostream>
#include <string>
#include "Tree.h"
#include "KeyCodePair.h"
using namespace std;
int main()
{
Tree tree = Tree();
KeyCodePair testPair = KeyCodePair("teststring1",10);
KeyCodePair qwePair = KeyCodePair("teststring2", 20);
cout << tree.Insert(testPair) << endl;
cout << tree.Insert(qwePair) << endl; // problem on second insert
if (tree.Search(testPair) == true) cout << "Found\n";
else cout << "Not Found\n";
cin.get();
return 0;
}
Let's take a look at your insert function:
Tree::treeNode* Tree::Insert(KeyCodePair data) {
if (root == NULL) {
root = getNewNode(data);
}
else if (data.getCode() <= root->data.getCode()) {
root->left = Insert(data);
}
else {
root->right = Insert(data);
}
return root;
}
What you do here is you take in the data to be inserted, and you look at the root. If there is no root, you add a new node containing the data and assign that to the root (which is why your first insert works). However, once there is a root, you then figure out if the new node should be placed to the left or right of the root, and then recursively call Insert() with the same data. This next call to Insert will do nothing different, and look at the same root of the tree over and over to most likely produce an infinite loop.
What you have to do is using your data, first traverse all the way down the tree to the position at which you want to insert your node, then insert it and assign the pointers. Some code for this might look like so:
Tree::Insert(KeyCodePair data) {
// currPos will end up being the position where we want to insert
Tree::treeNode* currPos = root;
while (currPos != NULL) {
if (data.getCode() <= currPos->data.getCode())
currPos = currPos->left;
else if (data.getCode() > currPos->data.getCode())
currPos = currPos->right;
}
// Insert at currPos and reassign the left or right pointer of
// the parent
}
The problem is that your insert only considers the root node. You need to traverse down the tree to the point where you do the insert:
class Tree {
...
public:
treeNode* Insert(KeyCodePair data);
...
};
Step 1: Change your interface
class Tree {
...
// The insert that does the work
// We pass in the current position in the tree.
treeNode* Insert(treeNode* node, KeyCodePair data);
public:
// The public interface that accepts the data and calls the internal Insert
void Insert(KeyCodePair data);
...
};
Step 2: Use the public Insert to call the internal Insert.
void Tree::Insert(KeyCodePair data) {
// Use the internal Insert() passing the root as the starting point.
// If a new value is needed it will be returned otherwise the original
// value is returned.
root = Insert(root, data);
}
Step 3: Modify the OP Insert into an Internal Insert.
Tree::treeNode* Tree::Insert(treeNode* node, KeyCodePair data) {
if (node == NULL) {
// If we have reached the tip of the tree then
// return the new node so it can be inserted.
return getNewNode(data);
}
// Otherwise we have a node so we need to find the node
// were the data will be inserted.
// so move to the next level. Assign the result as the next
// level could be null.
if (data.getCode() <= root->data.getCode()) {
node->left = Insert(node->left, data);
}
else {
node->right = Insert(node->right, data);
}
// Return this node
// So it stays in the chain.
return node;
}

Binary Search Tree Insertion C++ rooted at current node

I need to add an item to a binary tree given only the item to be added.
Here is the code I'm given:
void BinaryTree::add(Data * data) {
if (root == NULL) {
root = new BinaryTreeNode(data);
}
else {
root->add(data);
}
}
where root is a private variable of a BinaryTree defined as a BinaryTreeNode.
I need to implement a method:
void BinaryTreeNode::add(Data * data);
where a BinaryTreeNode is:
class BinaryTreeNode {
public:
Data * nodeData;
BinaryTreeNode * left;
BinaryTreeNode * right;
/**
* Constructor
*/
BinaryTreeNode(
Data * data,
BinaryTreeNode * left = NULL,
BinaryTreeNode *right = NULL
)
: nodeData(data), left(left), right(right)
{ }
// ...
I want to do this recursively, but I'm not positive how when you're only passed the data to be added.
My idea that doesn't work is:
void BinaryTreeNode::add(Data * newData) {
BinaryTreeNode * temp = this;
if (temp == NULL) {
temp->nodeData = newData;
} else {
if (newData->compareTo(nodeData) < 0) {
temp->left->add(newData);
} else {
temp->right->add(newData);
}
}
}
You are setting temp to this and then comparing it to NULL. this should never be NULL. You need to check if the left and right are NULL.
Well a binary tree, atleast how I know how to implement involves something like the following with two objects, one containing the the treenode object, and the other acting as an interface for the whole tree.
class cBinaryTree {
public:
bool insert(int inData);
//Other operations
private:
cBinaryTreeNode* root;
bool leftInsertion;
cBinaryTreeNode* getRoot() { return root; }
As you are comparing the actually value of the input data and placing it accordingly, this qualifies as a binary search tree. Then the insertion function can be written as
bool cBinaryTree::insert(int inData) {
//handle case if its first node.
cBinaryTreeNode *Parent = getInsertionNodePosition(getRoot(), inData);
cBinaryTreeNode *newNode = createNewNode(inData);
if(leftInsertion) //insert into left. add return statement
Parent->setLeftChild() = newNode;
else //insert into right
}
The recursive lookup function will be something like
cBinaryTreeNode* getInsertionNodePosition(cBinaryTreeNode* node,int inData) {
//Check left subtree and proceed from there.
if(inData < node->getData()) {
if(node->getLeftChild() == NULL) {
leftInsertion = true;
return node;
}
else {
node = node->getLeftChild();
return getInsertionNodePosition(node, inData);
}
}
//Similarly Check right subtree.
Hope this helps.

c++ binarysearchtree insert

I'm working on a project where I have to make a binary search tree that stores strings and takes account of doubles. While i've already tackled the specifics, I can't for the life of me get this damn insert function to work. It seems to only store the root node, leaving it's "children" NULL even though it does actually seem to assign the left and right pointers to new nodes. However when I attempt to output it, only the main parent (root) node exists. I guess the changes do not get saved for whatever reason.
Here's the header file:
#ifndef BST_H
#define BST_H
#include <string>
#include <vector>
#include <iostream>
using namespace std;
typedef string ItemType;
class Node
{
public:
Node(); // constructor
ItemType data; // contains item
Node* left; // points to left child
Node* right;// points to right child
int dataCount; // keeps track of repeats
vector<int> lineNumber; // keeps track of line numbers
};
class Tree
{
public:
Tree(); // constructor
// ~Tree(); // destructor. not working.
bool isEmpty(); // tests for empty tree
Node* find(Node* root, ItemType item); // finds an item
void insert(Node* root, ItemType item, int lineN, Tree tree); // inserts an item
void outputTree(Node* root); // lists all items in tree
void treeStats(Tree tree); // outputs tree stats
void clearTree(); // erases the tree (restart)
Node* getRoot(); // returns the root
void setRoot(Node*& root);
// void getHeight(Tree *root); // gets height of tree
private:
Node* root; // root of tree
int nodeCount; // number of nodes
};
#endif
cpp:
#include "BST.h"
bool setRootQ = true;
/** Node constructor- creates a node, sets children
* to NULL and ups the count. */
Node::Node()
{
left = right = NULL;
dataCount = 1;
}
/** Tree constructor- creates instance of tree
* and sets parameters to NULL */
Tree::Tree()
{
root = NULL;
nodeCount = 0;
}
/** Destructor- deallocates tree/node data;
* avoids heap leaks. SOMETHING WRONG. CAUSES SEGFAULT
Tree::~Tree()
{
if(this->root->left) // if a left child is present
{
delete this->root->left; //recursive call to destructor ("~Tree(->left)")
this->root->left = NULL;
}
if(this->root->right) // if a right child is present
{
delete this->root->right; //recursive call to destructor
this->root->right = NULL;
}
} */
/** Returns true if tree is empty.
* Otherwise returns false (DUH). */
bool Tree::isEmpty()
{
return root == NULL;
}
/** Searches tree for item; returns the node if found
* #param root- tree node.
* item- data to look for. */
Node* Tree::find(Node* root, ItemType item)
{
if(root == NULL) // if empty node
{
return NULL;
}
else if(item == root->data) // if found
{
return root;
}
else if(item < root->data) // if item is less than node
{
find(root->left, item);
}
else if(item > root->data) // if item is more than node
{
find(root->right, item);
}
return NULL;
}
/** Adds a new node to the tree. If duplicate, increases count.
* #param item- data to insert.
* root- tree node/ */
void Tree::insert(Node* root, ItemType item, int lineN, Tree tree)
{
Node* temp = find(tree.getRoot(), item);
if(temp != NULL) // if item already exists
{
temp->dataCount += 1;
temp->lineNumber.push_back(lineN);
return;
}
if(root == NULL) // if there is an empty space
{
root = new Node; // insert new node
root->data = item; // w/ data value
root->lineNumber.push_back(lineN);
nodeCount++;
if(setRootQ)
{
setRoot(root);
setRootQ = false;
}
return;
}
if(item < root->data)
{
insert(root->left, item, lineN, tree);
}
if(item > root->data)
{
insert(root->right, item, lineN, tree);
}
}
/** Outputs tree to console in inorder.
* #param root- tree root. */
void Tree::outputTree(Node* root)
{
if(isEmpty()) // if empty tree
{
cout << "Error: No items in tree" << endl; // error message
}
else
{
if(root->left != NULL)
{
outputTree(root->left);
}
cout << "- " << root->data << " (" << root->dataCount << ") line#s: ";
for(unsigned int i = 0; i < root->lineNumber.size(); i++)
{
cout << root->lineNumber[i] << ", ";
}
cout << endl;
if(root->right != NULL)
{
outputTree(root->right);
}
}
}
/** Displays tree stats including number of nodes,
* tree height, and more frequent item.
* #param tree- tree instance. */
void Tree::treeStats(Tree tree)
{
cout << "Number of entries: " << nodeCount << endl;
// unfinished
}
/** Clears tree.
void Tree::clearTree()
{
this->~Tree();
} */
/** Returns the root of the tree. */
Node* Tree::getRoot()
{
return root;
}
void Tree::setRoot(Node*& rootS)
{
root = rootS;
}
I realize my destructor isn't working but I'll tackle that myself later. I've been pulling my hair out over this trying to figure out what I'm missing, but to no avail. If anyone can give me any help and point me in the direction towards a solution I would greatly appreciate it.
i think it might have something to do with
void Tree::insert(Node* root, ItemType item, int lineN, Tree tree)
and instead should be something like
void Tree::insert(Node* &root, ItemType item, int lineN, Tree tree)
but when i try i get a "no matching function" error. :/
The solution you suggest yourself (with insert() taking Node *& root) will work. You have to make a corresponding change to the .h file, AND also change getRoot() to return Node *& in both .h and .cc files.
This will work. But your code has other problems. For example, setRoot and setRootQ don't do anything useful, as far as I can tell. The fourth argument to insert() only confuses things and does nothing to detect duplicates. It should be removed. To detect a duplicate simply do if (item == root->data) just before you do if (item < root->data) in the insert() method (i.e. it'll be even more similar to find()).
Also, if anyone besides you will ever use your code, you shouldn't require passing in getRoot() to methods like find() and insert(). Instead, create private helper methods, like find_helper(Node*, Item) and insert_helper(Node*&,Item), and have the public methods call them with the root node as the first argument. E.g.:
Node *find(Item item) { return find_helper(root, item); }
This would also make the weird return type of getRoot() unnecessary, and you could change it back to returning the plain Node*, or get rid of that accessor altogether.
Seems like there is a lot of pointer comparison occurring but the pointer member variables are not being initialized. Ensure that the pointer member variables are initialized properly so that they evaluate properly in if statements.
Change from:
class Node
{
public:
Node(); // constructor
...
};
to
class Node
{
public:
Node() : left(0), right(0) {}
...
};