I'm trying to implement BST in c++ using recursion. However, I found myself in dilemma.
In the Insert function, I use reference TreeNode *&nodeto pass the function argument. I don't want make the reference const, because I need change node in Insert function. On the other side, when I call function like tree.Insert(10, tree.Getroot()), it occurs error because function Getroot creates temporary variable which can't not be assigned to non-const reference. And I know I can easily fix it by making the TreeNode *rootpublic, but I don't want do that.
What should I do to fix it or is there any better design? Please help, thanks in advance.
Here's the head file.
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
class TreeNode
{
public:
TreeNode(int x = 0,TreeNode* l = nullptr, TreeNode* r = nullptr)
: element(x), left(l), right(r) { }
int element;
TreeNode* left;
TreeNode* right;
};
class BST
{
public:
BST(TreeNode *t = nullptr) : root(t) {}
void Insert(int x, TreeNode*& node)
{
if (node == nullptr) {
node = new TreeNode(x, nullptr, nullptr);
if (node == nullptr)
std::cout << "Insert Failure" << std::endl;
}
else if (node->element < x) {
Insert(x, node->right); //easy to make a mistake
}
else if (node->element > x) {
Insert(x, node->left);
}
}
TreeNode *Getroot()
{
return root;
}
private:
TreeNode* root;
};
#endif
Implement Insert at a node level as well as tree level. Then the insert logic should either be handled at the root level by the tree or at depth by the node you're inserting at. I have an example tree implemented here. It might not be the best implementation but maybe it will be useful to you.
#ifndef __BINARYTREENODE__
#define __BINARYTREENODE__
class BinaryTreeNode {
public:
BinaryTreeNode(int);
int element;
BinaryTreeNode *left;
BinaryTreeNode *right;
};
#endif /* __BINARYTREENODE__ */
#ifndef __BINARYSEARCHTREE__
#define __BINARYSEARCHTREE__
#include "BinaryTreeNode.h"
using namespace std;
class BinarySearchTree {
public:
BinarySearchTree();
~BinarySearchTree();
void insert(int);
private:
BinaryTreeNode *root;
void insert(int, BinaryTreeNode * & n);
};
#endif /* __BINARYSEARCHTREE__ */
#include "BinarySearchTree.h"
#include <iostream>
using namespace std;
BinarySearchTree::BinarySearchTree(){}
void BinarySearchTree::insert(int element)
{
insert(element, this->root);
}
void BinarySearchTree::insert(int element, BinaryTreeNode* & n)
{
if (n == 0)
{
n = new BinaryTreeNode(element);
}
else if (n->element > element)
{
insert(element, n->left);
}
else if (n->element < element)
{
insert(element, n->right);
}
}
Related
I'm trying to just create a simple binary tree to store integers. I don't want to just create a struct node outside of my class BinaryTree and then instantiate an object of node* inside the BinaryTree class. I want to embed the node class in the BinaryTree class.
Here is the header file I've written so far for the project:
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
using namespace std;
class BinaryTree {
private:
class TreeNode {
public:
int Data;
TreeNode* Right;
TreeNode* Left;
TreeNode() : Right(nullptr), Left(nullptr) {}
TreeNode(int data, TreeNode* lnode = nullptr, TreeNode* rnode=nullptr) :
Data(data), Right(rnode), Left(lnode) {}
};
TreeNode* root;
public:
BinaryTree();
bool Empty() const;
bool NewNode(TreeNode* node, const int& new_element);
bool Insert(TreeNode* node, const int& new_element);
};
#endif
Here is the .cpp realization of these declarations:
#include <iostream>
using namespace std;
BinaryTree::BinaryTree() : root(nullptr) {
}
bool BinaryTree::Empty() const
{
return (root == nullptr) ? true : false;
}
bool BinaryTree::NewNode(TreeNode* node, const int& new_element)
{
TreeNode* new_node;
new_node = new TreeNode;
new_node->Data = new_element;
node = new_node;
return true;
}
bool BinaryTree::Insert(TreeNode* node, const int& new_element)
{
if (Empty())
{
return NewNode(node, new_element);
}
else if (new_element < node->Data)
{
return node->Left = Insert(node->Left, new_element);
}
else
{
return node->Right = Insert(node->Right, new_element);
}
}
The specific errors I'm looking at have to do with the bool BinaryTree::Insert function. I get error notifs on the assignment operator = at these two places:
(1): return node->Left = Insert(node->Left, new_element);
(2): return node->Right = Insert(node->Right, new_element);
The following error message shows up when I investigate:
E0513 a value of type "bool" cannot be assigned to an entity of type "BinaryTree::TreeNode *
I cannot for the life of me figure out how to fix this error or what it's specifically addressing. Other examples of a binary search tree with an embedded class utilize these techniques, and yet I cannot make these assignment operators work. I have also tried to change the return type of the functions, without any success.
I have created a node.h class, defining a class called node for representing a binary tree(any type). It seems to be that the constructor isn't working. The errors are below.Ive only started writing constructors within classes like these, and this is the first ive encountered binary trees. Can anyone point me in the right direction on how to fix these errors and make my code work? Thanks.
Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
//an object of type node holds 3 things
// - an item (oftype t)
// - a left subtree
// - a right subtree
template<typename T>
class Node {
public:
Node(T item); //constructor to create a leaf node
Node(T item, Node *lft, Node *rht); //constructor which creates an internal node
~Node(); //Destructor
//public data member functions:
bool searchTree(T key);
void printTree();
private:
//private data member functions:
//..
};
//constructor
template<typename T>
Node<T>::Node(T i, Node<T> *l, Node<T> *r) {
item = i;
lft = NULL;
rht = NULL;
}
//constructor //is this correct?
template <typename T>
Node<T>::Node(T i) { //should i be a parameter here?
item = i; //is this right?
}
//destructor
template <typename T>
Node<T>::~Node() {
delete left;
delete right;
//delete;
}
//print tree method
template <typename T>
void Node<T>::printTree() {
if (lft != NULL) {
lft->printTree();
cout << item << endl;//alphabetical order
}
if (rht != NULL) {
rht->printTree();
//cout << item << endl; //post order
}
}
//search Tree method
template <typename T>
bool Node<T>::searchTree(T key) {
bool found = false;
if (item == key) {
return true;
}
if (left != NULL) {
found = left->searchTree(key);
if (found) return true;
}
if (right != NULL) {
return right->searchTree(key);
}
return false; //if left and right are both null & key is not the search item, then not found == not in the tree.
}
#endif
Main.cpp
#include "Node.h"
#include <iostream>
using namespace std;
//set up tree method
Node<string> *setUpTree() {
Node<string> *s_tree =
new Node<string>("Sunday",
new Node<string>("monday",
new Node<string>("Friday"),
new Node<string>("Saturday")),
new Node<string>("Tuesday",
new Node<string>("Thursday"),
new Node<string>("Wednesday")));
}
int main() {
Node<string> *s_tree;
s_tree = setUpTree();
cout << "Part 2 :Priting tree vals " << endl << endl;
s_tree->printTree();
cout << endl;
//search for range of tree values
//searchTree(s_tree, "Sunday");
//searchTree(s_tree, "Monday");
return 0;
}
There is no declarations of members you use in your constructor and other methods. The compiler does not know what rht or right means. Judging from your code the class should look more like this:
template<typename T>
class Node {
public:
Node(T item); //constructor to create a leaf node
Node(T item, Node *lft, Node *rht); //constructor which creates an internal node
~Node(); //Destructor
//public data member functions:
bool searchTree(T key);
void printTree();
private:
Node* left;
Node* right;
T item;
//private data member functions:
//..
};
So now the compiler knows what left, right and item mean. Now you can use these identifiers inside member functions of that class. Note that compiler still does not know what rht or lft are, so you should replace them with right and left.
Hope this helps
We have an assignment to create a Binary Search Tree with some basic functions. I feel I'd be capable of scraping by if it weren't for the files included with the assignment that we need to adhere to in order for the graders to implement our code with their grading program. Students are given a file called "Factory.cpp" which has a function that attempts to return an object of "BinarySearchTree" (return new BinarySearchTree();). However, VS 2013 gives me the error seen in the title. After some research, I can't find any infomration I can implement into my own problem to get rid of the error. Template classes are obviously more abstract and I can't find out what to include/leave out, etc to make things work.
The following is my incomplete code I have so far in my BinarySearchTree.h:
#pragma once
#include "BSTInterface.h"
#include "NodeInterface.h"
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
struct BTNode :public NodeInterface{
// Data Fields
int data;
BTNode* left;
BTNode* right;
// Constructor
BTNode(const int& the_data,
BTNode* left_val = NULL,
BTNode* right_val = NULL) :
data(the_data), left(left_val), right(right_val) {}
// Destructor (to avoid warning message)
virtual ~BTNode() {}
// Interface Functions
int getData(){
return data;
}
NodeInterface* getLeftChild(){
return left;
}
NodeInterface* getRightChild(){
return right;
}
}; // End BTNode
#include <sstream>
template<class T>
class BinarySearchTree:public BSTInterface
{
public:
BTNode* root;
// BST Constructor / Deconstructor
BinarySearchTree() : root(NULL){}
//BinarySearchTree(const int& the_data,
// const BinarySearchTree& left_child = BinarySearchTree(),
// const BinarySearchTree& right_child = BinarySearchTree()) :
// root(new BTNode(the_data, left_child.root, right_child.root)){}
virtual ~BinarySearchTree(){}
// Interface Functions ----------------------
NodeInterface* getRootNode(){
return root;
}
bool add(int data){
return addRec(root, data);
}
bool addRec(BTNode* &x, int data){
if (x == NULL){
if (Search(root, data) == true){
return false;
}
else{
root = GetNewNode(data);
return true;
}
}
if (data == x->data){
return false;
}
if (x != NULL){
if (data < x->data){
return addRec(x->left, data);
}
if (data > x->data){
return addRec(x->right, data);
}
}
}
bool remove(int data){
return false;
}
bool removeRec(BTNode* &x, int data){
return false;
}
void clear(){
}
// ------------------------------------------
// My Functions -----------------------------
BTNode* GetNewNode(int data){
BTNode* newNode = new BTNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
bool Search(BTNode* root, int data) {
if (root == NULL) {
return false;
}
else if (root->data == data) {
return true;
}
else if (data < root->data) { // had <= instead
return Search(root->left, data);
}
else if (data > root->data) { // had no "if"
return Search(root->right, data);
}
}
// ------------------------------------------
};
#endif
Which is derived from the following 2 "Interface" files:
NodeInterface.h:
//YOU MAY NOT MODIFY THIS DOCUMENT
#pragma once
#include <iostream>
class NodeInterface {
public:
NodeInterface() {}
virtual ~NodeInterface() {}
/*Returns the data that is stored in this node*/
virtual int getData() = 0;
/*Returns the left child of this node or null if it doesn't have one.*/
virtual NodeInterface * getLeftChild() = 0;
/*Returns the right child of this node or null if it doesn't have one.*/
virtual NodeInterface * getRightChild() = 0;
};
BSTInterface.h
//YOU MAY NOT MODIFY THIS DOCUMENT
#pragma once
#include "NodeInterface.h"
using namespace std;
class BSTInterface {
public:
BSTInterface() {}
virtual ~BSTInterface() {}
//Please note that the class that implements this interface must be made
//of objects which implement the NodeInterface
/*Returns the root node for this tree*/
virtual NodeInterface * getRootNode() = 0;
/*Attempts to add the given int to the BST tree*/
virtual bool add(int data) = 0;
/*Attempts to remove the given int from the BST tree*/
virtual bool remove(int data) = 0;
/*Removes all nodes from the tree, resulting in an empty tree.*/
virtual void clear() = 0;
};
Then they give us "Factory.h" and "Factory.cpp," which I believe they use to grab our BinarySearchTree from in order to grade using their grading program:
Factory.h:
#include "BSTInterface.h"
using namespace std;
/*
WARNING: It is expressly forbidden to modify any part of this document, including its name
*/
class Factory
{
public:
static BSTInterface * getBST();
};
Factory.cpp:
#include "Factory.h"
#include "BinarySearchTree.h"
//You may add #include statements here
/*
You will MODIFY THIS DOCUMENT.
getBST()
Creates and returns an object whose class extends BSTInterface.
This should be an object of a class you have created.
Example: If you made a class called "BinarySearchTree", you might say, "return new BinarySearchTree();".
*/
BSTInterface * Factory::getBST()
{
return new BinarySearchTree();//Modify this line
}
In "Factory.cpp", BinarySearchTree is marked as an error in VS with the message "argument list for class template is missing." How do I fix this? Along with any other errors you see.
Also, how would I declare a new BinarySearchTree object in a main() and call its functions in order to test it?
For that error, in these lines:
template<class T>
class BinarySearchTree:public BSTInterface
{
just get rid of the first line. That line is telling the compiler that you BinarySearchTree class is a template class. But since your class uses an int for data it would seem that is not needed.
I haven't looked at your other code so I won't comment on anything else.
I'm new to C++. I'm trying to implement a LinkedList, for which I created two classes Node and LinkedList.
I created some test functions. One to test the Node creation and another to test the isEmpty function from LinkedList. However, when I try to test them. What's created in 'testNode()ends up being in the same Node I create insideLinkedListashead`.
This may be trivial question, however as a newcomer to C++ this concept is still no clear to me. I'd like to know why it is referring to the same instance created previously.
#include <iostream>
#include <assert.h>
using namespace std;
class Node
{
private:
int data;
int next;
public:
int getData(){return data;}
void setData(int new_data) {data = new_data;}
int getNext(){return next;}
void setNext(int new_next) {next = new_next;}
};
class LinkedList
{
Node head;
Node head2;
public:
bool isEmpty()
{
if (head.getData() == 0) {return true;}
return false;
}
};
void testNode()
{
Node aNode;
aNode.setData(15);
aNode.setNext(23);
assert (aNode.getData() == 15);
assert (aNode.getNext() == 23);
}
void testEmptyLinkedList()
{
LinkedList ll;
assert (ll.isEmpty() == true);
}
Initialize your data.
int data = 0;
int next = 0;
Live On Coliru
#include <iostream>
#include <cassert>
using namespace std;
class Node {
private:
int data = 0;
int next = 0;
public:
int getData() { return data; }
void setData(int new_data) { data = new_data; }
int getNext() { return next; }
void setNext(int new_next) { next = new_next; }
};
class LinkedList {
Node head;
Node head2;
public:
bool isEmpty() {
if (head.getData() == 0) {
return true;
}
return false;
}
};
void testNode() {
Node aNode;
aNode.setData(15);
aNode.setNext(23);
assert(aNode.getData() == 15);
assert(aNode.getNext() == 23);
}
void testEmptyLinkedList() {
LinkedList ll;
assert(ll.isEmpty() == true);
}
int main() {
testEmptyLinkedList();
}
If your intention is to implement LinkList, each node of the list should contain the address of the next one.
So "next" shoud be declared as a pointer to a Node. Same for the first node of the list.
class Node {
private:
int data;
Node *next;
....
};
class LinkedList {
private:
Node *head;
...
};
I'm confused about how pointers work here. I have a class called PrefixTree and a struct called TreeNode within this class. I have the following code to build a tree with a string, the problem is every time preorder() is called it doesn't return the root character correctly and after that it throws a segmentation fault.
I want to know if I'm correctly setting the root pointer or if I'm misusing it in the others files.
//prefixtree.cpp
PrefixTree::TreeNode* PrefixTree::buildTree(string& input)
{
char c = input[0];
input.erase(0,1);
TreeNode* node = new TreeNode();
node->character = c;
if (!root)
root = node;
if (c == '*')
{
node->left = buildTree(input);
node->right = buildTree(input);
}
return node;
}
void PrefixTree::preorder()
{
traverse(root);
}
void PrefixTree::traverse(TreeNode* node)
{
if (node)
{
cout << node->character << endl;
traverse(node->left);
traverse(node->right);
}
}
and
//prefixtree.h
class PrefixTree
{
private:
struct TreeNode
{
char character;
TreeNode* left;
TreeNode* right;
};
TreeNode* root;
void traverse(TreeNode* node);
public:
TreeNode* buildTree(string& input);
void preorder();
};
and
//main.cpp
PrefixTree tree;
string a = string("*a**!*dc*rb");
cout << tree.buildTree(a)->character << endl;
tree.preorder();
You need to initialize the pointer members, they are not automatically initialized and may contain garbage values instead of nullptr, which leads to your tests if(!root) and if(node) being useless, reporting uninitialized pointers as valid, which you will then dereference.
Add constructors:
class PrefixTree
{
private:
struct TreeNode
{
char character;
TreeNode* left;
TreeNode* right;
TreeNode() : character('a'), left(nullptr), right(nullptr) {};
};
TreeNode* root;
void traverse(TreeNode* node);
public:
PrefixTree() : root(nullptr) {};
TreeNode* buildTree(string& input);
void preorder();
};