As you may have noticed from the title I have diverse classes specifically 3 and each one respond to a different tree implementation.
In Tree1.h
class Tree1 {
public:
struct node{
char label;
node* nHMI_ptr;
node* nHD_ptr;
};
node* root;
Tree1();
~Tree1();
bool Empty();
Tree1::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
In Tree2.h
class Tree2 {
public:
struct node{
char label;
node* nHMI_ptr;
node* nHD_ptr;
node* nFather_ptr;
node* nHI_ptr;
};
node* root;
Tree2();
~Tree2();
bool Empty();
Tree2::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
In Tree3.h
class Tree3{
public:
Tree3();
~Tree3();
struct node;
struct nodeSon{
struct node* node_ptr;
nodeSon* nextNodeSon_ptr;
};
struct node{
char label;
node* nextNode_ptr;
struct nodeSon* nSon;
};
node* root;
bool Empty();
Tree3::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
As you can see they have functions and members under the same name or identifier. This is because I want to make various more complex algorithms using this functions but the tricky part is that I want to make this algortihms independent of the class being used. The first thing that came to my mind was to create this algorithms on my main.cpp.
In main.cpp
#include <cstdlib>
#include <iostream>
#include "Tree1.h"
//#include "Tree2.h"
//#include "Tree3.h"
void someFunc(node n) {
//do something by calling Tree functions
//E.g. call Empty(), call AddSon(...)
}
int main(int argc, char** argv) {
return 0;
}
What I am trying to achive is that someFunc(...) works on all of the trees without changing any of the underlying code and just by enabiling one of the #include and disabling the other two.
Is it possible to do it?
How can I accomplish this?
Is it possible to do it?
Yes
How can I accomplish this?
You simply can provide a template function:
template<class TreeType>
void someFunc(TreeType& treeContext, typename TreeType::node& n) {
//do something by calling Tree functions
//E.g. call Empty(), call AddSon(...)
}
Related
I am trying to write code to offload the inorder contents of a Binary Tree into a vector.
IE:
#include <iostream>
#include <vector>
#include "BinaryTree.h"
using namespace std;
int main()
{
BinaryTree tree;
vector <double> v;
// Test iterative insert
cout << "Inserting the numbers 5 8 3 12 9.";
tree.insert(5);
tree.insert(8);
tree.insert(3);
tree.insert(12);
tree.insert(9);
// Test vectorExport()
tree.vectorExport(v);
}
I am getting a whole bunch of errors because I don't think I'm implementing it correctly in the member function. I don't know if I'm using the & symbol in the wrong spot or its not in a place it should be. Anyones help would be appreciated.
This is the error I am getting:
[Error] prototype for 'void BinaryTree::vectorExport(BinaryTree::TreeNode*, std::vector<double>&)' does not match any in class 'BinaryTree'
Here is my class:
#ifndef DOUBLEBINARYTREE_H
#define DOUBLEBINARYTREE_H
#include <iostream>
#include <vector>
using namespace std;
class BinaryTree
{
private:
// The TreeNode class is used to build the tree.
class TreeNode
{
friend class BinaryTree;
double value;
TreeNode *left;
TreeNode *right;
TreeNode(double value1, TreeNode *left1 = NULL,
TreeNode *right1 = NULL)
{
value = value1;
left = left1;
right = right1;
}
};
TreeNode *root; // Pointer to the root of the tree
// Various helper member functions.
void insert(TreeNode *&, double);
bool search(TreeNode *, double);
void destroySubtree(TreeNode *);
void remove(TreeNode *&, double);
void makeDeletion(TreeNode *&);
void vectorExport(TreeNode *, vector<double>);
public:
// These member functions are the public interface.
BinaryTree() // Constructor
{ root = NULL; }
~BinaryTree() // Destructor
{ destroySubtree(root); }
void insert(double num)
{ insert(root, num); }
bool search(double num)
{ search(root, num); }
void remove(double num)
{ remove(root, num);}
void vectorExport(vector<double> & v)
{ vectorExport(root, v); }
};
Here is the actual function:
//*********************************************************
// This function offloads tree contents to a vector *
//*********************************************************
void BinaryTree::vectorExport(TreeNode *tree, vector<double> &v)
{
if (tree)
{
vectorExport(tree->left, vector<double> v);
v.push_back(tree->value);
vectorExport(tree->right, vector <double> v);
}
}
Declare the argument as being passed by reference, e.g.
void vectorExport(TreeNode *, vector<double>&);
not
void vectorExport(TreeNode *, vector<double>);
I have implemented each of the methods for this class but I am struggling with this last error. I was given instructions to define the Node struct within the private section of the class linkedlist. I get errors such as:
"error: Node is not a class template"
and
"error: non-template type 'Node' used as a template"
My code works if I rearrange things and place the Node struct outside of the class altogether, but that is not really the solution I am looking for.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
typedef int element_type;
template<class element_type>
class linkedlist
{
private:
struct Node<element_type>{
Node<element_type>* next;
Node<element_type>* prev;
element_type data;
};
Node<element_type>* head;
Node<element_type>* tail;
unsigned int size;
public:
linkedlist();
~linkedlist();
void push_back(const element_type& z);
void push_front(const element_type& z); //add front
void print() const;
// will initialize list with n nodes
explicit linkedlist(unsigned int n);
};
The TL;DR version is to drop the template syntax on Node:
struct Node{
Node* next;
Node* prev;
element_type data;
};
Node* head;
Node* tail;
Because Node is defined inside the class template, it can already access the type element_type. The compiler error is just telling you that you can't use template syntax when declaring a structure which is not itself a template.
Just remove template parameter from struct Node.
struct Node {
Node * next;
Node * prev;
element_type data;
};
Node * head;
Node * tail;
unsigned int size;
I'm trying a classic programming interview problem. The idea is to create a balanced binary tree(or a tree with minimum height) from a sorted array. This is my node class.
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
node* sortedArrayToBinaryTree(int arr[], int start, int end){
if(start > end) return nullptr;
int mid = (start + end)/2;
node* p = new node(arr[mid]);
p->left = sortedArrayToBinaryTree(arr, start, mid-1);
p->right = sortedArrayToBinaryTree(arr, mid+1, end);
return p;
}
void preorder(node* root){
if(root == nullptr) return;
std::cout<<root->value<<" "<<std::endl;
preorder(root->left);
preorder(root->right);
}
private:
int value;
node* left;
node* right;
};
I'm reasonably sure that my logic is ok. However the issue is when I write a client code to test the functionality my public methods in node class are not being resolved.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = sortedArrayToBinaryTree();
preorder();
return 0;
}
I get the following compilation error.
error: use of undeclared identifier 'sortedArrayToBinaryTree'
node* root = sortedArrayToBinaryTree(arr, 0, 5);
^
main.cpp:10:5: error: use of undeclared identifier 'preorder'
preorder();
^
2 errors generated.
You forgot not only to pass actual arguments to the functions, but the fact, that these non-static member functions (methods) need a class instance to be called on. I don't see any.
Nevertheless, it doesn't make sense to make sortedArrayToBinaryTree and preorder members of node. If you're making a tree, there should be class tree that takes care of the sorting/ordering etc... So, logic is not OK.
Function sortedArrayToBinaryTree is a non-static member function of class node.
It may not be called withput an object of this class.
You could declare it as a static data member in the class definition
static node* sortedArrayToBinaryTree(int arr[], int start, int end){
//...
and in this case you could write
node* root = node::sortedArrayToBinaryTree( /* arguments */ );
And as the function does not have default arguments you have to specify them explicitly.
The same is applied to funcion preorder.
Take into account that these functions do not use data members of the class. So the class design is wrong.
I think you should declare these functions as static member functions of the class.
You are getting compiler errors since the functions sortedArrayToBinaryTree and preorder are declared in node as member functions and you are using them from main as though they are non-member functions.
I can think of the following ways you can resolve the problem.
Make the functions non-member functions
Declare the functions.
node* sortedArrayToBinaryTree(int arr[], int start, int end);
void preorder(node* root);
Make them friends of node.
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
friend node* sortedArrayToBinaryTree(int arr[], int start, int end);
friend void preorder(node* root);
private:
int value;
node* left;
node* right;
};
And then use them from main, with right arguments.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = sortedArrayToBinaryTree(arr, 0, sizeof(arr)/sizeof(arr[0]));
preorder(root);
return 0;
}
Make the functions static member functions
class node{
public:
node(int data):value(data), left(nullptr), right(nullptr){}
static node* sortedArrayToBinaryTree(int arr[], int start, int end);
static void preorder(node* root);
private:
int value;
node* left;
node* right;
};
and call them from main.
int main() {
int arr[] = {2,7,9,13,19,21};
node* root = node::sortedArrayToBinaryTree(arr, 0, sizeof(arr)/sizeof(arr[0]));
node::preorder(root);
return 0;
}
For a school project I am trying to make a binary search tree at the same time we are supposed to learn how to use 'friendship' in classes. The errors I get while compiling are: [I put comments in code where the errors originate from for clarity] (Keep in mind I am not allowed to nest Node in the BST class they are both supposed to be in separate files and classes for the sake of this programming assignment)
BST.cpp: In member function `void BST::insert(std::string, std::string)':
BST.cpp:11: error: `get_key' undeclared (first use this function)
BST.cpp:11: error: (Each undeclared identifier is reported only once for each function it appears in.)
BST.cpp: At global scope:
BST.cpp:5: warning: unused parameter 'data'
makefile.txt:9: recipe for target `BST.o' failed
make: *** [BST.o] Error 1
I want to be able to access the functions in Node.cpp to be able to retrieve its private members for the sake of the binary search tree. In BST.cpp so far I am attempting to compare a string 'key' that is passed into the 'insert' function with the string that 'xPtr' is currently pointing to. The classes are defined as: Node.h (directly below)
#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class BST;
class Node
{
public:
Node(string key, string data)
{m_key = key; m_data = data;}
~Node();
string get_key(Node *ptr); //takes in ptr to node and returns its key
string get_data(Node *ptr); //takes in ptr to node and returns its data
Node* get_left(Node *ptr); //takes in ptr to node and returns its left child pointer
Node* get_right(Node *ptr); //takes in ptr to node and returns its right child pointer
private:
string m_key;
string m_data;
Node *m_left;
Node *m_right;
};
#endif // NODE_H_INCLUDED
Node.cpp
#include "Node.h"
string Node::get_key(Node* ptr)
{
return ptr->m_key;
}
string Node::get_data(Node* ptr)
{
return ptr->m_data;
}
Node* Node::get_left(Node* ptr)
{
return ptr->m_left;
}
Node* Node::get_right(Node* ptr)
{
return ptr->m_right;
}
BST.h
#ifndef BST_H_INCLUDED
#define BST_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class BST
{
public:
BST()
{m_root = NULL;}
~BST();
void insert(string key, string data);
void find(string key);
void remove(string key, string data);
void print();
friend class Node;
private:
Node* m_root;
};
#endif // BST_H_INCLUDED
BST.cpp
#include "BST.h"
#include "Node.h"
void BST::insert(string key, string data)
{
Node* yPtr = NULL;
Node* xPtr = m_root;
while(xPtr != NULL)
{
yPtr = xPtr;
if(key < get_key(xPtr)) //error: 'get_key' undeclared (first use this function)
{
}
}
}
Well... basically you are calling non-existing function. When you use get_key(xPtr) inside a BST you are calling BSD::get_key(Node*). You are allowed to call Node::get_key(Node*) but since it's not a static function (which you'd call by Node::get_key(xPtr)) you have to use the object:
if (key < xPtr->get_key(xPtr))
If you wanted to use it like:
Node::get_key(xPtr)
you have to mark Node::get_key(Node*) as static:
// Node.h
class BST;
class Node {
string m_key;
string m_data;
Node *m_left;
Node *m_right;
public:
Node(string key, string data) :
m_key(key),
m_data(data)
{}
~Node();
static string get_key(Node *ptr);
static string get_data(Node *ptr);
static Node* get_left(Node *ptr);
static Node* get_right(Node *ptr);
};
but even better would be:
// Node.h
class BST;
class Node {
string m_key;
string m_data;
Node *m_left;
Node *m_right;
public:
Node(string key, string data) :
m_key(key),
m_data(data)
{}
~Node();
string get_key();
string get_data();
Node* get_left();
Node* get_right();
};
and:
// BSD.cpp
string Node::get_key() {
return m_key;
}
string Node::get_data() {
return m_data;
}
Node* Node::get_left() {
return m_left;
}
Node* Node::get_right() {
return m_right;
}
Then you'd be able to use it like this:
void BST::insert(string key, string data)
{
Node* yPtr = NULL;
Node* xPtr = m_root;
while (xPtr != NULL) {
yPtr = xPtr;
if (key < xPtr->get_key()) { // actual object-oriented programming
}
}
}
On a side note: don't use using namespace std in header to declare its usage globally - it's not a good thing to do.
"get_key" is not a member of BST, so you cannot just call it from BST member function (even though it's a friend class).
You may call xPtr->get_key(xPtr), that should work.
But, the implementation of get_key is problematic, because it's not really using the data string of itself, but of the given xPtr parameter. to correct this you may :
make get_key a static method of Node (and call it using Node::get_key(xPtr))
change get_key to return this->data (and call it using xPtr->get_key());
good luck!
I'm implementing a doubly linked list and I'm using an object of my own as the data being stored.
Here is my object:
#ifndef PLAY_H_INCLUDED
#define PLAY_H_INCLUDED
#include <string>
class Play
{
private:
int m_quarter;
int m_minutes;
std::string oTeam;
std::string dTeam;
int m_down;
int m_yardToGO;
int m_startLoc;
int playDesc;
std::string wholePlay;
int relevance;
int relCounter;
public:
int getQuarter();
int getMinutes();
std::string getoTeam();
std::string getdTeam();
int getDown();
int getYard();
int getStartLoc();
int getPlayDesc();
std::string getwholePlay();
Play(int quarter, int minutes, std::string offense, std::string defense, int dwn, int ytg, int start, int desc, std::string play, int relevance, int relCounter);
~Play();
Play parse(std::string toParse);
std::string findPlay(std::string playDesc);
};
#endif // PLAY_H_INCLUDED
-
Here is my node:
template<class T>
class node{
friend class Play;
T data;
node *next, *prev;
node(const T& t, node *n = 0, node *p = 0) {data=t; next=n; prev=p;}
};
The exact error I get is:
error: node<Play>* node<Play>::next is private.
I assume I get this problem because Play's information is private and inaccessible to node, and to fix this I tried making node a friend class of Play. When I did that I get errors saying "node is not a template type". The error makes no sense to me so I assume this isn't the way to correct my problem.
Thanks.
Use public: above properties which should be public. If you don't specify anything, everything becomes private.
template<class T>
class node{
public: // ADD THIS
friend class Play;
T data;
node<T> *next, *prev;
node(const T& t, node<T> *n = 0, node<T> *p = 0) { // EDIT
data=t; next=n; prev=p;
}
};
Edit: You always need use <> when using template classes, like I edited in above.
All attributes in a class are private by default. Make it a struct instead or add public: at the beginning.
But I guess that is not the problem. When using node *next, *prev;, use this instead:
typedef typename node<T>* MyType;
MyType *next, *prev;