I don't know, why _clear don't remove elements from a tree. Probably, needs to override destructor.
class Node {
T _val;
Node *_left;
Node *_right;
int _height;
explicit Node(T _val = T()) : _val(_val), _left(nullptr), _right(nullptr), _height(1) {};
friend class AVL_Tree<T>;
};
void AVL_Tree<T>::_clear(Node<T>*vertex) {
if(vertex != nullptr) {
_clear(vertex->_left);
_clear(vertex->_right);
delete vertex;
}
vertex = nullptr;
}
There are stay NULL linked nodes, why they don't delete?
The problem is here:
AVL_Tree<T>::_clear(Node<T>*vertex)
You passed a pointer to Node by value, but you want to change the pointer and have the change propagate out of the function. The C++ way to do this is pass a reference to the pointer-to-Node:
AVL_Tree<T>::_clear(Node<T>*&vertex)
PS. Don't begin an identifier with an underscore. That's reserved for library implementers. So:
AVL_Tree<T>::clear(Node<T>*&vertex)
I've stumbled upon a problem with my linked list class.
I've one abstract class Shape and multiple classes inheriting from it, like Square or Triangle etc.
I'm storing them in my List class but I don't know how to return stored object back to the pointer of Shape.
Since my explanation may seem pretty vague here is some code with expected behaviour explained.
class Shape // abstract class
{
public:
int a;
//some member virtual methods
};
class Square : public Shape
{
//using the virtual methods from Shape
};
In my main file, this is how I want to use it:
int main()
{
List<Shape*> ShapeList;
Shape *ptr;
Square a(2, 1, 1); // size, x, y coordinates
ShapeList.add(ptr);
//up to this point everything works well
// now I want my list to return a pointer to it's member
// so I can modify it
Shape *listptr;
listptr = ShapeList.findInstanceAt(0); // here's my error
listptr->a = 5; // what I want to do next
}
So as you can see I'm havingtroubles with returning proper value from my list and I don't know how to solve this.
Here's my simplified list implementation:
template <class T> class Node
{
T data;
Node *next;
public:
inline T getData()
{
return data;
}
inline Node* getNext()
{
return next;
}
};
template <class T> class List
{
Node<T> *head, *tail;
public:
List() : head(NULL), tail(NULL) { }
T* findInstanceAt(int _k)
{
if (NULL == head)
{
cout << "\nList is empty.";
return NULL;
}
else
{
Node<T> *temp = new Node<T>;
temp = head;
for (size_t k = 0; k < _k; ++k)
{
if (NULL != temp->getNext()) temp = temp->getNext();
else return NULL;
}
return temp->getData;
}
}
}
Thanks in advance for any suggestions on how to make this work.
#EDIT
Ahh I forgot to add compiler errors that I'm getting:
Error 1 error C2440: '=' : cannot convert from 'Shape **' to 'Shape *'
Do you want to store Shapes or pointers to Shapes in the list? And do you want the findInstanceAt to return the node in the list or a pointer to the node in the list? At the moment you are not consistent on these things
You store Shape* nodes in the list but the findInstanceAt returns a pointer to the node - which is a Shape** object. This is what the compiler is complaining about
You probaly need to chang
T* findInstanceAt(int _k)
to
T findInstanceAt(int _k)
I have a class "poly" and a class "node". The class poly is made from a linked list of nodes. I am trying to pass a poly to a function "printPoly" that will allow me to print the linked list of nodes. But I am having trouble accessing the variables of the nodes...
Here is my code:
class Node
{
private:
double coeff;
int exponent;
Node *next;
public:
Node(double c, int e, Node *nodeobjectPtr)
{
coeff = c;
exponent = e;
next = nodeobjectPtr;
}
};
class poly
{
private:
Node *start;
public:
poly(Node *head) /*constructor function*/
{
start = head;
}
void printPoly(); //->Poly *p1 would be the implicit parameter
};
void poly :: printPoly()
{
poly *result = NULL;
result = this;
double c;
int e;
Node *result_pos = res->start; //create ptr to traverse linked nodes
while(result_pos!= NULL)
{
c = result_pos->coeff; // I CANT ACCESS THESE???
e = result_pos->exponent;
printf(....);
result_pos = result_pos->next; //get next node (also can't access "next")
}
I think it has something to do with the fact that "coeff, exponent, and next" are private variables of the node class. But since my poly class is made up of nodes shouldn't it be able to access these?
Private variables and functions in a class can only be accessed by the function inside that class.
Anything you want to use from outside of that class (e.g. the way you are now) has to be public.
so I am very new to C++ programming so I apologize beforehand if I am asking something trivial. My assignment is to add, multiply and evaluate polynomials where each term of a specified polynomial is represented by a Node class with private variables: double coefficient, int power and Node *next.
class Node{
private:
double coef;
int power;
Node *next;
public: blah
}
The head to that linked list (for each polynomial), is to be stored in an array of Poly objects where the only private variable in my Poly class is Node *head.
class Poly{
private:
Node *head;
public:poly functions;
}
The user is to select the polynomial they want to work with by selecting an element from my polynomial array, and this will give the head to the selected polynomial.
poly_array[n];
However my issue now is that the element of this array is of object Poly and I want to make it of class Node so I can actually extract its contents of the class and use this method to transverse through the nodes of the selected polynomial(s).
This is the code I have tried to implement to make this work but my function call of convert poly returns garbage. I am lost as to what method I should try next. Thank you in advance.
This is where I try to first transverse a polynomial to display its contents.
void init_polydisplay(vector<Poly*> polynomial_array, int numofpolys)
{
Poly *polyobject;
Node *polyhead;
for (int n = 0; n < numofpolys; n++)
{
temp3.getnodehead();
polyhead=polyobject->convertPoly(polynomial_array[n]);
}
}
My attempt at trying to return Node* versus just the head of the polynomial.
Node* Poly::convertPoly(Poly* tmp)
{
return (Node *) tmp;
}
You can define a get_head() function in Poly
class Poly{
private:
Node *head;
public:
Node * get_head()
{
return head;
}
};
and use it this way:
polyhead = polynomial_array[n]->get_head();
I would like to ask you how to write a copy constructor (and operator = ) for the following classes.
Class Node stores coordinates x,y of each node and pointer to another node.
class Node
{
private:
double x, y;
Node *n;
public:
Node (double xx, double yy, Node *nn) : x(xx), y(yy), n(nn) {}
void setNode (Node *nn) : n(nn) {}
...
};
Class NodesList (inherited from std:: vector) stores all dynamically allocated Nodes
class NodesList : public std::vector<Node *>
{}
The main program:
int main()
{
Node *n1 = new Node(5,10,NULL);
Node *n2 = new Node(10,10,NULL);
Node *n3 = new Node(20,10,NULL);
n1->setNode(n2);
n2->setNode(n3);
n3->setNode(n2);
NodesList nl1;
nl1.push_back(n1);
nl1.push_back(n2);
nl1.push_back(n3);
//Copy contructor is used, how to write
NodesList nl2(nl1);
//OPerator = is used, how to write?
NodesList nl3 = nl1;
}
I do not want to create a shallow copy of each node but a deep copy of each node. Could I ask you for a sample code with copy constructor?
Each node can be pointed more than once. Let us have such situation, when 3 nodes n[1], n[2], n[3] are stored in the NodesList nl1:
n[1] points to n[2]
n[2] points to n[3]
n[3] points to n[2]
A] Our copy constructor process the node n[1]. It creates a new object n[1]_new represented by the copy of the old object n[1]_old. The node n[2] pointed from n[1]_old still does not exist, so n[2]_new must be also created... The pointer from n1_new to n2_new is set.
B] Then second point n[2] is processed. It can not be created twice, n[2]_new was created in A]. But pointed node n[3] does not exist, so the new object n[3]_new as a copy of an old object n[3]_old is created. The pointer from n2_new to n3_new is set.
C] Node n[3]_new has already been created and n[2]_new. The pointer from n3_new to n2_new is set and no other object will be created...
So the copy constructor should check whether the object has been created in the past or has not...
Some reference counting could be helpful...
There is my solution of the problem. A new data member n_ref storing a new verion of the node n was added:
class Node
{
private:
double x, y;
Node *n, *n_ref;
public:
Node (double xx, double yy, Node *nn) : x(xx), y(yy), n(nn) {n_ref = NULL;}
Node * getNode() {return n;}
Node * getRefNode () {return n_ref;}
void setNode (Node *nn) {this->n = nn;}
void setRefNode (Node *nn) {this->n_ref = nn;}
The copy constructor creates a shallow copy of the node:
Node (const Node *node)
{
x = node->x;
y = node->y;
n = node->n;
n_ref = node->n_ref;
}
The copy constructor for NodesList
NodesList::NodesList(const NodesList& source)
{
const_iterator e = source.end();
for (const_iterator i = source.begin(); i != e; ++i) {
//Node* n = new Node(**i);
//Node n still has not been added to the list
if ((*i)->getRefNode() == NULL)
{
//Create node
Node *node = new Node(*i);
//Add node to the list
push_back(node);
//Set this note as processed
(*i)->setRefNode(node);
//Pointed node still has not been added to the list
if ((*i)->getNode()->getRefNode() == NULL)
{
//Create new pointed node
Node *node_pointed = new Node ((*i)->getNode());
//Add node to the list
push_back(node_pointed);
//Set pointer to n
node->setNode(node_pointed);
//Set node as processed
((*i)->getNode())->setRefNode(node_pointed);
}
//Pointed node has already been added to the list
else
{
//Set pointer to node n
node->setNode((*i)->getRefNode());
}
}
//Node n has already been added to the list
else
{
//Get node
Node * node = (*i)->getRefNode();
//Pointed node still has not been added
if ((*i)->getNode()->getRefNode() == NULL)
{
//Create new node
Node *node_pointed = new Node ((*i)->getNode());
//Add node to the list
push_back(node_pointed);
//Set pointer to n
node->setNode(node_pointed);
//Set node as processed
((*i)->getNode())->setRefNode(node_pointed);
}
//Pointed node has already been added to the list
else
{
//Set pointer to n
node->setNode((*i)->getNode()->getRefNode());
}
}
}
}
Perform a shallow copy in NodeList::NodeList(const NodeList&) and you don't have to worry about cycles breaking the copy operation. Disclaimer: the following is untested, incomplete and may have bugs.
class NodeList {
private:
typedef std::vector<Node*> Delegate;
Delegate nodes;
public:
NodeList(int capacity=16) : nodes() { nodes.reserve(capacity); }
NodeList(const NodeList& from);
virtual ~NodeList();
NodeList& operator=(const NodeList& from);
/* delegated stuff */
typedef Delegate::size_type size_type;
typedef Delegate::reference reference;
typedef Delegate::const_reference const_reference;
typedef Delegate::iterator iterator;
typedef Delegate::const_iterator const_iterator;
size_type size() const { return nodes.size(); }
iterator begin() { return nodes.begin(); }
const_iterator begin() const { return nodes.begin(); }
iterator end() { return nodes.end(); }
const_iterator end() const { return nodes.end(); }
// ...
};
NodeList::NodeList(const NodeList& from)
: nodes(from.size()), flags(NodeList::owner)
{
std::map<Node*, Node*> replacement;
Delegate::const_iterator pfrom;
Delegate::iterator pto;
// shallow copy nodes
for (pfrom=from.begin(), pto=nodes.begin();
pfrom != from.end();
++pfrom, ++pto)
{
replacement[*pfrom] = *pto = new Node(**pfrom);
}
// then fix nodes' nodes
for (pto = nodes.begin(); pto != nodes.end(); ++pto) {
(*pto)->setNode(replacement[(*pto)->getNode()]);
}
}
NodeList::operator=(const NodeList&) can use the copy-swap idiom, the same as Tronic's Node::operator=(const Node&).
This design has a potential memory leak in that a copied NodeList is (initally) the only place that references its nodes. If a temporary NodeList goes out of scope, a poor implementation will leak the Nodes the list contained.
One solution is to proclaim that NodeLists own Nodes. As long as you don't add a Node to more than one NodeList (via NodeList::push_back, NodeList::operator[] &c), NodeList's methods can delete nodes when necessary (e.g. in NodeList::~NodeList, NodeList::pop_back).
NodeList::~NodeList() {
Delegate::iterator pnode;
for (pnode = nodes.begin(); pnode != nodes.end(); ++pnode) {
delete *pnode;
}
}
void NodeList::pop_back() {
delete nodes.back();
nodes.pop_back();
}
Another solution is to use smart pointers, rather than Node*. NodeList should store shared pointers. Node::n should be a weak pointer to prevent ownership cycles.
I would just use std::list<Node> instead of NodesList. Well, let's code...
NodesList::NodesList(const NodesList& source)
{
const_iterator e = source.end();
for (const_iterator i = source.begin(); i != e; ++i) {
Node* n = new Node(**i);
push_back(n);
}
}
Apparently each Node is only allowed to point to another Node in the same list? Otherwise the "deep copy" of a list needs more definition. Should it not be connected to the original NodeList? Should it not be connected to any original Node? Are copies of Nodes not in the list being copied added to some other list or free-floating?
If all the Node-to-Node pointers are constrained within the NodeList, then perhaps you should store indexes instead of pointers, then no special handling is required.
You should not inherit from standard library containers (because they lack virtual destructors). Instead, include them as member variables in your classes.
Since you want a deep copy, you need these: (rule of three)
Node(Node const& orig): x(orig.x), y(orig.y), n() {
if (orig.n) n = new Node(*orig.n);
}
Node& operator=(Node const& orig) {
// The copy-swap idiom
Node tmp = orig;
swap(tmp); // Implementing this member function left as an exercise
return *this;
}
~Node() { delete n; }
A better idea might be to avoid using pointers entirely and just put your nodes in a suitable container.