What I want is a rather simple binary search tree that via the template tag, allows for any numerical data to be used within it, but I'm having some rather obnoxious issues that I have no clue of how to get rid off, if anyone can help, it would be much appreciated. The error message that keeps popping up for me is "Invalid use of template-name 'BST' without an argument list" - and quite frankly I have no clue how to solve it. It occurs on line 31, 89, 105, 120, 130, 141 in the bst.cpp file:
Main.cpp
#include <iostream>
#include "bst.h"
using namespace std;
int main()
{
BST <int> tree;
tree.insert(8);
tree.insert(25);
tree.insert(99);
tree.insert(20);
tree.insert(25);
tree.insert(20);
tree.insert(2);
tree.insert(89);
tree.insert(15);
tree.insert(10);
tree.insert(30);
tree.insert(50);
tree.displayorder();
int number;
int Inputnumber;
while (true){
cout << "Choose what you want to do: " << endl << "1# Insert" << endl << "2# Display Orders" << endl << "3# Search" << endl << "4# Delete" << endl << endl << endl;
cin >> Inputnumber;
if (Inputnumber==1){
cout << endl << "Enter the number you want inserted: ";
cin >> number;
tree.insert(number);
cout << endl << endl << endl;
}
if (Inputnumber==2){
cout<<"Display Orders: " << endl;
tree.displayorder();
cout << endl << endl << endl;
}
if (Inputnumber==3){
cout<<"Enter the number you want to search for: ";
cin >> number;
tree.search(number);
cout << endl << endl << endl;
}
if (Inputnumber==4){
cout << "Enter the number you want to remove: ";
cin >> number;
tree.remove(number);
cout << endl << endl << endl;
}
}
}
bst.h
#ifndef BST_H
#define BST_H
template <class T>
class BST
{
struct node
{
T data;
node* left;
node* right;
};
node* root;
node* makeEmpty(node* tree);
node* insert(T x, node* tree);
node* findMin(node* tree);
node* findMax(node* tree);
node* remove(T x, node* tree);
void inorder(node* tree);
void preorder(node* tree);
void postorder(node* tree);
public:
BST();
~BST();
node* find(node* tree, T x);
void insert(T x);
void remove(T x);
void displayorder();
void search(T x);
};
#endif // BST_H
bst.cpp
#include <iostream>
#include "bst.h"
using namespace std;
template <class T>
void BST<T>::preorder(node* tree)
{
if(tree == NULL){
return;
}
cout << tree->data << " ";
inorder(tree->left);
inorder(tree->right);
}
template <class T>
void BST<T>::postorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
inorder(tree->right);
cout << tree->data << " ";
}
template <typename T>
BST::node* BST<T>::find(node* tree, T x) //AN ERROR OCCURS HERE
{
if(tree == NULL)
return NULL;
else if(x < tree->data)
return find(tree->left, x);
else if(x > tree->data)
return find(tree->right, x);
else
return tree;
}
template <typename T>
BST<T>::BST()
{
root = NULL;
}
template <typename T>
BST<T>::~BST()
{
root = makeEmpty(root);
}
template <class T>
void BST<T>::insert(T x)
{
root = insert(x, root);
}
template <class T>
void BST<T>::remove(T x)
{
root = remove(x, root);
}
template <class T>
void BST<T>::displayorder()
{
inorder(root);
cout << endl;
preorder(root);
cout << endl;
postorder(root);
cout << endl << endl;
}
template <class T>
void BST<T>::search(T x)
{
if(root = find(root, x)){
cout << endl << "Found!" << endl;
}
else{
cout << endl << "Not Found!" << endl;
}
}
template <class T>
BST::node* BST<T>::makeEmpty(node* tree) //AN ERROR OCCURS HERE
{
if(tree == NULL)
return NULL;
{
makeEmpty(tree->left);
makeEmpty(tree->right);
delete tree;
}
return NULL;
}
template <class T>
BST::node* BST<T>::insert(T x, node* tree) //AN ERROR OCCURS HERE
{
if(tree == NULL)
{
tree = new node;
tree->data = x;
tree->left = tree->right = NULL;
}
else if(x < tree->data)
tree->left = insert(x, tree->left);
else if(x >= tree->data)
tree->right = insert(x, tree->right);
return tree;
}
BST::node* BST::findMin(node* tree) //AN ERROR OCCURS HERE
{
if(tree == NULL)
return NULL;
else if(tree->left == NULL)
return tree;
else
return findMin(tree->left);
}
BST::node* BST::findMax(node* tree) //AN ERROR OCCURS HERE
{
if(tree == NULL)
return NULL;
else if(tree->right == NULL)
return tree;
else
return findMax(tree->right);
}
template <typename T>
BST::node* BST<T>::remove(T x, node* tree) //AN ERROR OCCURS HERE
{
node* temp;
if(tree == NULL)
return NULL;
else if(x < tree->data)
tree->left = remove(x, tree->left);
else if(x > tree->data)
tree->right = remove(x, tree->right);
else if(tree->left && tree->right)
{
temp = findMin(tree->right);
tree->data = temp->data;
tree->right = remove(tree->data, tree->right);
}
else
{
temp = tree;
if(tree->left == NULL)
tree = tree->right;
else if(tree->right == NULL)
tree = tree->left;
delete temp;
}
return tree;
}
template <class T>
void BST<T>::inorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
You need to qualify BST::node too, as BST<T>::node. Also, keep in mind that all the template code will need to live in bst.h because it will need to be instantiated by each source file that uses it (like main.cpp).
Add the
Add the BST::node in your function definitions. In addition include the .ipp (cpp file) as shown in line 27 in order to have the class methods in the header and the implementation in a .ipp file. You don't have to place all your template code in the header file if you don't wan't to.
Another tip is the fact that you must not pass the root node to your functions because anyone outside the class can have access to your tree root. Aim for something like the following code
1 #ifndef BST_H
2 #define BST_H
3
4 #include <memory>
5
6 template<typename T>
7 class node;
8
9 template <typename T>
10 class BST
11 {
12 public:
13 BST();
14 BST(std::initializer_list<T> init);
15 ~BST();
16
17 void make_empty();
18 bool is_empty() const noexcept;
19 bool is_full() const;
20 void insert(const T&);
21 void remove(const T&);
22 void print_tree() const noexcept;
23 private:
24 std::unique_ptr<node<T>> root;
25 };
26
27 #include "binary_search_tree.ipp"
28
29 #endif
Related
I tried creating a binary search tree, using youtube and examples from my professor to help, but display in Driver.cpp doesn't show any node of the tree except "null" (which was intended to represent nullptr). I think it's because my "root" remains as nullptr, even though I've inserted a new node. The output should be "23 null null". Sorry if the codes aren't short and optimized, I want to make things clear for myself when I reread them later.
P.S.: I've deleted some unfinished functions in the code posted here so there might be minor mistakes
//Driver.cpp
#include <iostream>
#include "Overall Tree.h";
using namespace std;
int main()
{
BinaryTree tree_1;
tree_1.insertNode(23);
tree_1.display();
return 0;
}
//Overall Tree.h
#include <iostream>
using namespace std;
class BinaryTree
{
struct Node
{
int data;
Node* left;
Node* right;
};
private:
Node* root;
public:
// Constructors and Destructors
BinaryTree();
//traversal functions
void preOrder();
void inOrder();
void postOrder();
void preOrderTraverse(Node*);
void inOrderTraverse(Node*);
void postOrderTraverse(Node*);
//display function
void display();
//insert functions
void insertNode(int);
void insert(Node*, Node*);
};
BinaryTree::BinaryTree()
{
root = nullptr;
}
//display traversals
void BinaryTree::display()
{
cout << "Pre-order traversal: " << endl;
preOrder();
cout << endl << endl;
cout << "In-order traversal: " << endl;
inOrder();
cout << endl << endl;
cout << "Post-order traversal: " << endl;
postOrder();
}
// traversals
void BinaryTree::preOrder()
{
preOrderTraverse(root);
}
void BinaryTree::inOrder()
{
inOrderTraverse(root);
}
void BinaryTree::postOrder()
{
postOrderTraverse(root);
}
void BinaryTree::preOrderTraverse(Node* root)
{
if (root != nullptr)
{
cout << root->data << " ";
preOrderTraverse(root->left);
preOrderTraverse(root->right);
}
else
cout << "null ";
}
void BinaryTree::inOrderTraverse(Node* root)
{
if (root != nullptr)
{
preOrderTraverse(root->left);
cout << root->data << " ";
preOrderTraverse(root->right);
}
else
cout << "null ";
}
void BinaryTree::postOrderTraverse(Node* root)
{
if (root != nullptr)
{
preOrderTraverse(root->left);
preOrderTraverse(root->right);
cout << root->data << " ";
}
else
cout << "null ";
}
//insert
void BinaryTree::insertNode(int x)
{
Node* newNode = new Node;
newNode->data = x;
newNode->left = nullptr;
newNode->right = nullptr;
insert(newNode, this->root);
}
void BinaryTree::insert(Node* newNode, Node* p)
{
if (p == nullptr)
p = newNode;
else
if (newNode->data < p->data)
insert(newNode, p->left);
else if (newNode->data > p->data)
insert(newNode, p->right);
else
cout << "Value already existed in the tree.";
}
You should pass pointer to pointer to root in your insert function like:
void BinaryTree::insert(Node* newNode, Node** p)
{
if (*p == nullptr) {
*p = newNode;
} else {
if (newNode->data < (*p)->data) {
insert(newNode, &(*p)->left);
} else if (newNode->data > (*p)->data) {
insert(newNode, &(*p)->right);
} else {
cout << "Value already existed in the tree.";
}
}
}
and then use this function like:
insert(newNode, &this->root);
Why pointer to pointer?
Because you want modifications of the parameter (in this case p parameter), made in the insert function, to affect the argument which the caller passed in.
EDIT
You can also use reference for this purpose:
void BinaryTree::insert(Node* newNode, Node*& p)
{
if (p == nullptr) {
p = newNode;
} else {
if (newNode->data < p->data) {
insert(newNode, p->left);
} else if (newNode->data > p->data) {
insert(newNode, p->right);
} else {
cout << "Value already existed in the tree.";
}
}
}
and then use it like:
insert(newNode, this->root);
I would suggest using reference because of the cleaner syntax IMO.
BST.cpp's overloaded move assignment operator:
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
Look at the cout << root << endl part that I commented on. When that piece of code is ran it prints out an address other than 00000000. It doesn't seem like they're being deleted correctly.
This is a code where the calling object's BST is deleted (all branches) and then it steals otherBST's tree. Move assignment operator. But why is it not printing a nullptr and instead printing another address? It doesn't seem like it's being deleted correctly.
Here's for reference:
This is the screenshot of test driver being ran: click here to see.
Main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
runTest();
cout << endl << endl;
system("Pause");
return 0;
}
Test.h
#include "BST.h"
void runTest() {
cout << "--------------------------------------------------------------------" << endl;
cout << "Binary Search Tree Test Driver" << endl;
cout << "--------------------------------------------------------------------" << endl;
// Initialization:
BST bst1;
// Traversal when there are no elements in the tree:
cout << "BST traversal when there are no elements within the tree (bst1): " << endl;
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting one element into the tree recursively and non-recursively (bst1): " << endl;
bst1.insert(21);
bst1.preorderTraversal();
cout << endl;
bst1.insert(69);
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting duplicate elements into the tree recursively (bst1): " << endl;
bst1.insert(32);
bst1.insert(32);
bst1.preorderTraversal();
cout << endl;
cout << "BST using the function destroyTree (bst1): " << endl;
bst1.destroyTree();
bst1.preorderTraversal();
cout << endl;
cout << "BST copy constructor by copy constructing bst1 (bst2): " << endl;
bst1.insert(21);
bst1.insert(69);
BST bst2(bst1);
bst2.preorderTraversal();
cout << endl;
cout << "BST move constructor by move constructing bst1 (bst3): " << endl;
BST bst3 = move(bst1);
bst3.preorderTraversal();
cout << endl;
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 has no elements in its tree: " << endl;
bst1.destroyTree();
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
bst1.destroyTree();
bst2.destroyTree();
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 already has some elements in its tree: " << endl;
bst1.insert(21);
bst1.insert(105);
bst1.insert(18);
bst1.insert(16);
bst1.insert(7);
bst1.insert(19);
bst1.insert(109);
bst1.insert(125);
bst1.insert(101);
bst2.insert(691);
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
}
BST.h
#ifndef BST_H
#define BST_H
#include <string>
#include <iostream>
#include <stack>
using namespace std;
class Node
{
friend class BST;
public:
Node() : data(0), rlink(nullptr), llink(nullptr) {}
~Node() {}
private:
int data;
Node *rlink, *llink;
};
class BST
{
public:
BST();
BST(const BST& otherBST);
BST(BST&& otherBST);
void insert(int item);
void insertNonRecursive(int item);
void preorderTraversal() const;
// BST& operator=(const BST& otherBST);
BST& operator=(BST&& otherBST);
void destroyTree();
~BST();
private:
Node * root; // Pointer to the root.
void copyConstructor(const Node *p);
void insert(Node* &p, Node *newNode);
void preorderTraversal(const Node *p) const;
void destroyTree(Node *&p);
};
#endif
BST.cpp
#include "BST.h"
BST::BST() : root(nullptr) {}
BST::BST(const BST& otherBST) {
copyConstructor(otherBST.root);
}
BST::BST(BST&& otherBST) {
root = move(otherBST.root);
otherBST.root = nullptr;
}
void BST::copyConstructor(const Node *p) {
if (p != nullptr) {
insert(p->data);
copyConstructor(p->llink);
copyConstructor(p->rlink);
}
}
void BST::insert(int insertItem)
{
Node *newNode = new Node;
newNode->data = insertItem;
insert(root, newNode);
}
void BST::insert(Node* &p, Node *newNode)
{
if (p == nullptr)
p = newNode;
else if (p->data > newNode->data)
insert(p->llink, newNode);
else
insert(p->rlink, newNode);
}
void BST::insertNonRecursive(int item) {
if (root == nullptr) {
root = new Node();
root->data = item;
}
else {
Node *current = root;
bool searching = true;
while (searching) {
if (item > current->data && current->rlink != nullptr) {
current = current->rlink;
}
else if (item < current->data && current->llink != nullptr) {
current = current->llink;
}
else if (item == current->data) {
cerr << "The item to insert is already in the list, duplicates are not allowed." << endl;
searching = false;
}
else {
if (item > current->data) {
current->rlink = new Node();
current->rlink->data = item;
}
else {
current->llink = new Node();
current->llink->data = item;
}
searching = false;
}
}
}
}
void BST::preorderTraversal() const {
if (root == nullptr)
cerr << "There is no tree.";
else
{
preorderTraversal(root);
}
}
void BST::preorderTraversal(const Node *p) const {
if (p != nullptr) {
cout << p->data << " ";
preorderTraversal(p->llink);
preorderTraversal(p->rlink);
}
}
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
void BST::destroyTree(Node* &p)
{
if (p != nullptr)
{
destroyTree(p->llink);
destroyTree(p->rlink);
delete p;
p = nullptr;
}
}
void BST::destroyTree()
{
destroyTree(root);
}
BST::~BST()
{
destroyTree(root);
}
I think the line you mentioned is just fine and is not leaking anything. It is just that the pointer isn't assigned to NULL.
You are probably doing expecting pA tobe NULL in below example
int *pA = new int;
int *pB = pA;
delete pB;
pB=NULL;
printf("pA=0x%p, pB=0x%p", pA,pAB);
Note that even though pA points to something,which is a dangling pointer now, there is no leak.
To get desired behavior, you can set the root to NULL after you are done pushing in stack.
What I want is a rather simple binary search tree that via the template tag, allows for any numerical data to be used within it, but I'm having some rather obnoxious issues that I have no clue of how to get rid off, if anyone can help, it would be much appreciated. The error message that keeps popping up for me is "Invalid use of template-name 'BST' without an argument list" - and quite frankly I have no clue how to solve it. It occurs on line 31, 89, 105, 120, 130, 141 in the bst.cpp file. Given that I'm not as proficient when it comes to binary search trees, I'd prefer as conclusive of an answer as possible (even going as far as to mention exactly where and what needs to be changed):
Main.cpp
#include <iostream>
#include "bst.h"
using namespace std;
int main()
{
BST <int> tree;
tree.insert(8);
tree.insert(25);
tree.insert(99);
tree.insert(20);
tree.insert(25);
tree.insert(20);
tree.insert(2);
tree.insert(89);
tree.insert(15);
tree.insert(10);
tree.insert(30);
tree.insert(50);
tree.displayorder();
int number;
int Inputnumber;
while (true){
cout << "Choose what you want to do: " << endl << "1# Insert" << endl << "2# Display Orders" << endl << "3# Search" << endl << "4# Delete" << endl << endl << endl;
cin >> Inputnumber;
if (Inputnumber==1){
cout << endl << "Enter the number you want inserted: ";
cin >> number;
tree.insert(number);
cout << endl << endl << endl;
}
if (Inputnumber==2){
cout<<"Display Orders: " << endl;
tree.displayorder();
cout << endl << endl << endl;
}
if (Inputnumber==3){
cout<<"Enter the number you want to search for: ";
cin >> number;
tree.search(number);
cout << endl << endl << endl;
}
if (Inputnumber==4){
cout << "Enter the number you want to remove: ";
cin >> number;
tree.remove(number);
cout << endl << endl << endl;
}
}
}
BST.cpp
#include <iostream>
#include "bst.h"
using namespace std;
template <class T>
void BST<T>::preorder(node* tree)
{
if(tree == NULL){
return;
}
cout << tree->data << " ";
inorder(tree->left);
inorder(tree->right);
}
template <class T>
void BST<T>::postorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
inorder(tree->right);
cout << tree->data << " ";
}
template <typename T>
BST::node* BST<T>::find(node* tree, T x) //ERROR HERE
{
if(tree == NULL)
return NULL;
else if(x < tree->data)
return find(tree->left, x);
else if(x > tree->data)
return find(tree->right, x);
else
return tree;
}
template <typename T>
BST<T>::BST()
{
root = NULL;
}
template <typename T>
BST<T>::~BST()
{
root = makeEmpty(root);
}
template <class T>
void BST<T>::insert(T x)
{
root = insert(x, root);
}
template <class T>
void BST<T>::remove(T x)
{
root = remove(x, root);
}
template <class T>
void BST<T>::displayorder()
{
inorder(root);
cout << endl;
preorder(root);
cout << endl;
postorder(root);
cout << endl << endl;
}
template <class T>
void BST<T>::search(T x)
{
if(root = find(root, x)){
cout << endl << "Found!" << endl;
}
else{
cout << endl << "Not Found!" << endl;
}
}
template <class T>
BST::node* BST<T>::makeEmpty(node* tree) //ERROR HERE
{
if(tree == NULL)
return NULL;
{
makeEmpty(tree->left);
makeEmpty(tree->right);
delete tree;
}
return NULL;
}
template <class T>
BST::node* BST<T>::insert(T x, node* tree) //ERROR HERE
{
if(tree == NULL)
{
tree = new node;
tree->data = x;
tree->left = tree->right = NULL;
}
else if(x < tree->data)
tree->left = insert(x, tree->left);
else if(x >= tree->data)
tree->right = insert(x, tree->right);
return tree;
}
BST::node* BST::findMin(node* tree) //ERROR HERE
{
if(tree == NULL)
return NULL;
else if(tree->left == NULL)
return tree;
else
return findMin(tree->left);
}
BST::node* BST::findMax(node* tree) //ERROR HERE
{
if(tree == NULL)
return NULL;
else if(tree->right == NULL)
return tree;
else
return findMax(tree->right);
}
template <typename T>
BST::node* BST<T>::remove(T x, node* tree) //ERROR HERE
{
node* temp;
if(tree == NULL)
return NULL;
else if(x < tree->data)
tree->left = remove(x, tree->left);
else if(x > tree->data)
tree->right = remove(x, tree->right);
else if(tree->left && tree->right)
{
temp = findMin(tree->right);
tree->data = temp->data;
tree->right = remove(tree->data, tree->right);
}
else
{
temp = tree;
if(tree->left == NULL)
tree = tree->right;
else if(tree->right == NULL)
tree = tree->left;
delete temp;
}
return tree;
}
template <class T>
void BST<T>::inorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
BST.h
#ifndef BST_H
#define BST_H
template <class T>
class BST
{
struct node
{
T data;
node* left;
node* right;
};
node* root;
node* makeEmpty(node* tree);
node* insert(T x, node* tree);
node* findMin(node* tree);
node* findMax(node* tree);
node* remove(T x, node* tree);
void inorder(node* tree);
void preorder(node* tree);
void postorder(node* tree);
public:
BST();
~BST();
node* find(node* tree, T x);
void insert(T x);
void remove(T x);
void displayorder();
void search(T x);
};
#endif // BST_H
By example, in
BST::node* BST<T>::find(node* tree, T x)
you forget the <T> component for the first BST.
Should be
// vvv
BST<T>::node* BST<T>::find(node* tree, T x)
All other errors are of the same type.
A class template like the BST you are apparently using is not a type. It's a recipe for creating a class type. What the error message is trying to tell you is that (almost) anywhere you use the name BST, you need to supply template arguments immediately after it inside <angle brackets>.
For example, in
template <class T>
BST::node* BST<T>::makeEmpty(node* tree) //ERROR HERE
the compiler is complaining about the first instance of BST in the return type, not the one that correctly specifies BST<T> as the class type. This should probably be:
template <class T>
BST<T>::node* BST<T>::makeEmpty(node* tree)
[There are at least two exceptions to this general rule. One is that the name of a template alone can be used as a template argument to another template which expects a template instead of a type or value.
The other is called the "injected class name": Inside the scope of a class template, including a class template member, you can use just the name of the template as an alias to the "current" specialization.
So in fact you could also use a trailing return type and do:
template <class T>
auto BST<T>::makeEmpty(node* tree) -> BST::node*
In the above, since the return type now comes after the BST<T>:: and not before, it is now in the scope of the class template, so you are allowed to use just BST as an alias for BST<T>.]
So, I've made a binary search tree, but now I'm stuck, as I have to make it into a template, yet my knowledge of templates are rather limited and if someone could, I'd appreciate it if they could "spoonfeed" me how to convert the tree into one that would work for any numerical data, thanks in advance!
Main.cpp
#include <iostream>
#include "bst.h"
using namespace std;
int main()
{
BST tree;
tree.insert(8);
tree.insert(25);
tree.insert(99);
tree.insert(20);
tree.insert(25);
tree.insert(20);
tree.insert(2);
tree.insert(89);
tree.insert(15);
tree.insert(10);
tree.insert(30);
tree.insert(50);
tree.displayorder();
int number;
int Inputnumber;
while (true){
cout << "Choose what you want to do: " << endl << "1# Insert" << endl << "2# Display Orders" << endl << "3# Search" << endl << "4# Delete" << endl << endl << endl;
cin >> Inputnumber;
if (Inputnumber==1){
cout << endl << "Enter the number you want inserted: ";
cin >> number;
tree.insert(number);
cout << endl << endl << endl;
}
if (Inputnumber==2){
cout<<"Display Orders: " << endl;
tree.displayorder();
cout << endl << endl << endl;
}
if (Inputnumber==3){
cout<<"Enter the number you want to search for: ";
cin >> number;
tree.search(number);
cout << endl << endl << endl;
}
if (Inputnumber==4){
cout << "Enter the number you want to remove: ";
cin >> number;
tree.remove(number);
cout << endl << endl << endl;
}
}
}
Bst.cpp
#include <iostream>
#include "bst.h"
using namespace std;
BST::node* BST::makeEmpty(node* tree)
{
if(tree == NULL)
return NULL;
{
makeEmpty(tree->left);
makeEmpty(tree->right);
delete tree;
}
return NULL;
}
BST::node* BST::insert(int x, node* tree)
{
if(tree == NULL)
{
tree = new node;
tree->data = x;
tree->left = tree->right = NULL;
}
else if(x < tree->data)
tree->left = insert(x, tree->left);
else if(x >= tree->data)
tree->right = insert(x, tree->right);
return tree;
}
BST::node* BST::findMin(node* tree)
{
if(tree == NULL)
return NULL;
else if(tree->left == NULL)
return tree;
else
return findMin(tree->left);
}
BST::node* BST::findMax(node* tree)
{
if(tree == NULL)
return NULL;
else if(tree->right == NULL)
return tree;
else
return findMax(tree->right);
}
BST::node* BST::remove(int x, node* tree)
{
node* temp;
if(tree == NULL)
return NULL;
else if(x < tree->data)
tree->left = remove(x, tree->left);
else if(x > tree->data)
tree->right = remove(x, tree->right);
else if(tree->left && tree->right)
{
temp = findMin(tree->right);
tree->data = temp->data;
tree->right = remove(tree->data, tree->right);
}
else
{
temp = tree;
if(tree->left == NULL)
tree = tree->right;
else if(tree->right == NULL)
tree = tree->left;
delete temp;
}
return tree;
}
void BST::inorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
void BST::preorder(node* tree)
{
if(tree == NULL){
return;
}
cout << tree->data << " ";
inorder(tree->left);
inorder(tree->right);
}
void BST::postorder(node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
inorder(tree->right);
cout << tree->data << " ";
}
BST::node* BST::find(node* tree, int x)
{
if(tree == NULL)
return NULL;
else if(x < tree->data)
return find(tree->left, x);
else if(x > tree->data)
return find(tree->right, x);
else
return tree;
}
BST::BST()
{
root = NULL;
}
BST::~BST()
{
root = makeEmpty(root);
}
void BST::insert(int x)
{
root = insert(x, root);
}
void BST::remove(int x)
{
root = remove(x, root);
}
void BST::displayorder()
{
inorder(root);
cout << endl;
preorder(root);
cout << endl;
postorder(root);
cout << endl << endl;
}
void BST::search(int x)
{
if(root = find(root, x)){
cout << endl << "Found!" << endl;
}
else{
cout << endl << "Not Found!" << endl;
}
}
Bst.h
#ifndef BST_H
#define BST_H
class BST
{
struct node
{
int data;
node* left;
node* right;
};
node* root;
node* makeEmpty(node* tree);
node* insert(int x, node* tree);
node* findMin(node* tree);
node* findMax(node* tree);
node* remove(int x, node* tree);
void inorder(node* tree);
void preorder(node* tree);
void postorder(node* tree);
public:
BST();
~BST();
node* find(node* tree, int x);
void insert(int x);
void remove(int x);
void displayorder();
void search(int x);
};
#endif // BST_H
You could do that by using the following changes:
In your BST.h file, add the following above the class decleration:
template < typename T >
class BST {
[...]
}
Then, foreach method definition, change it to:
template < typename T >
typename BST<T>::node* BST<T>::makeEmpty(BST<T>::node* tree)
{
if(tree == NULL)
return NULL;
{
makeEmpty(tree->left);
makeEmpty(tree->right);
delete tree;
}
return NULL;
}
Then, search and replace int with T in both BST.h and BST.cpp.
And then in your main.cpp change the variable to BST<int> tree.
The result should be this:
#include <iostream>
using namespace std;
template < typename T >
class BST
{
struct node
{
T data;
node* left;
node* right;
};
node* root;
node* makeEmpty(node* tree);
node* insert(T x, node* tree);
node* findMin(node* tree);
node* findMax(node* tree);
node* remove(T x, node* tree);
void inorder(node* tree);
void preorder(node* tree);
void postorder(node* tree);
public:
BST();
~BST();
node* find(node* tree, T x);
void insert(T x);
void remove(T x);
void displayorder();
void search(T x);
};
template < typename T >
typename BST<T>::node* BST<T>::makeEmpty(BST<T>::node* tree)
{
if(tree == NULL)
return NULL;
{
makeEmpty(tree->left);
makeEmpty(tree->right);
delete tree;
}
return NULL;
}
template < typename T >
typename BST<T>::node* BST<T>::insert(T x, BST<T>::node* tree)
{
if(tree == NULL)
{
tree = new node;
tree->data = x;
tree->left = tree->right = NULL;
}
else if(x < tree->data)
tree->left = insert(x, tree->left);
else if(x >= tree->data)
tree->right = insert(x, tree->right);
return tree;
}
template < typename T >
typename BST<T>::node* BST<T>::findMin(BST<T>::node* tree)
{
if(tree == NULL)
return NULL;
else if(tree->left == NULL)
return tree;
else
return findMin(tree->left);
}
template < typename T >
typename BST<T>::node* BST<T>::findMax(BST<T>::node* tree)
{
if(tree == NULL)
return NULL;
else if(tree->right == NULL)
return tree;
else
return findMax(tree->right);
}
template < typename T >
typename BST<T>::node* BST<T>::remove(T x, BST<T>::node* tree)
{
node* temp;
if(tree == NULL)
return NULL;
else if(x < tree->data)
tree->left = remove(x, tree->left);
else if(x > tree->data)
tree->right = remove(x, tree->right);
else if(tree->left && tree->right)
{
temp = findMin(tree->right);
tree->data = temp->data;
tree->right = remove(tree->data, tree->right);
}
else
{
temp = tree;
if(tree->left == NULL)
tree = tree->right;
else if(tree->right == NULL)
tree = tree->left;
delete temp;
}
return tree;
}
template < typename T >
void BST<T>::inorder(BST<T>::node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
template < typename T >
void BST<T>::preorder(BST<T>::node* tree)
{
if(tree == NULL){
return;
}
cout << tree->data << " ";
inorder(tree->left);
inorder(tree->right);
}
template < typename T >
void BST<T>::postorder(BST<T>::node* tree)
{
if(tree == NULL){
return;
}
inorder(tree->left);
inorder(tree->right);
cout << tree->data << " ";
}
template < typename T >
typename BST<T>::node* BST<T>::find(BST<T>::node* tree, T x)
{
if(tree == NULL)
return NULL;
else if(x < tree->data)
return find(tree->left, x);
else if(x > tree->data)
return find(tree->right, x);
else
return tree;
}
template < typename T >
BST<T>::BST()
{
root = NULL;
}
template < typename T >
BST<T>::~BST()
{
root = makeEmpty(root);
}
template < typename T >
void BST<T>::insert(T x)
{
root = insert(x, root);
}
template < typename T >
void BST<T>::remove(T x)
{
root = remove(x, root);
}
template < typename T >
void BST<T>::displayorder()
{
inorder(root);
cout << endl;
preorder(root);
cout << endl;
postorder(root);
cout << endl << endl;
}
template < typename T >
void BST<T>::search(T x)
{
if(root = find(root, x)){
cout << endl << "Found!" << endl;
}
else{
cout << endl << "Not Found!" << endl;
}
}
int main()
{
BST<int> tree;
tree.insert(8);
tree.insert(25);
tree.insert(99);
tree.insert(20);
tree.insert(25);
tree.insert(20);
tree.insert(2);
tree.insert(89);
tree.insert(15);
tree.insert(10);
tree.insert(30);
tree.insert(50);
tree.displayorder();
int number;
int Inputnumber;
while (true){
cout << "Choose what you want to do: " << endl << "1# Insert" << endl << "2# Display Orders" << endl << "3# Search" << endl << "4# Delete" << endl << endl << endl;
cin >> Inputnumber;
if (Inputnumber==1){
cout << endl << "Enter the number you want inserted: ";
cin >> number;
tree.insert(number);
cout << endl << endl << endl;
}
if (Inputnumber==2){
cout<<"Display Orders: " << endl;
tree.displayorder();
cout << endl << endl << endl;
}
if (Inputnumber==3){
cout<<"Enter the number you want to search for: ";
cin >> number;
tree.search(number);
cout << endl << endl << endl;
}
if (Inputnumber==4){
cout << "Enter the number you want to remove: ";
cin >> number;
tree.remove(number);
cout << endl << endl << endl;
}
}
}
I was working this code previously but have a new issue with it the link to the old one is Bloodshed Dev-C++ compiler errors *Binary Trees.
I have one error that states in function 'int main()' no matching function for call to 'binaryTreeType::insert(int&)' candidates are: void binaryTreeType::insert () [with elemType = int] not really sure what this is. The code is posted below any help is appreciated thanks in advance.
#include <iostream>
using namespace std;
template <class elemType>
struct nodeType
{
int data;
nodeType *lLink;
nodeType *rLink;
};
template <class elemType>
class binaryTreeType //main class
{
public:
binaryTreeType(); //constructor
~binaryTreeType(); //destructor
void swapSubtreeNodes(); //declares swapSubtreeNodes
void swapSubtreeNodes(nodeType<elemType>*);
void insert();
void printTree();
private:
nodeType<elemType>*root; //declares root pointer
nodeType<elemType> *temp; //declares root pointer
};
template <class elemType>
void binaryTreeType<elemType>::swapSubtreeNodes()
{
swapSubtreeNodes(root); //displays new root
}
template <class elemType>
void binaryTreeType<elemType>::swapSubtreeNodes(nodeType<elemType> *p)
{
root = temp;
nodeType<elemType> *root; //pointer for root
nodeType<elemType> *temp; //pointer for temp
if (p == NULL) //checks for empty pointer
{
return;
}
else
{
swapSubtreeNodes(p->lLink); //do the subtrees
swapSubtreeNodes(p->rLink);
temp = p->lLink; //swap the pointers
p->lLink = p->rLink;
p->rLink = temp;
}
root = temp; //root set equal to temp
}
int main()
{
binaryTreeType<int> (tree);
int num;
cout << "This is how we swap'em" << endl;
cout << "Insert number (press enter after each one entered)." << endl;
cout << "Enter -999 to complete" << endl;
binaryTreeType<int> (insert);
cin >> num;
while (num != -999)
{
tree.insert(num);
cin >> num;
}
cout << "The unswapped binary tree looks like this: " << endl;
tree.printTree();
cout << endl;
cout << "The swapped binary tree looks like this: " << endl;
tree.swapSubtreeNodes();
tree.printTree();
cout << endl;
}
The template member function binaryTreeType<elemType>::insert() takes no arguments. The code tries to call it with an argument of type int.
Your insert method declaration doesn't take any parameters.