I came across the following code and despite some help from others, I am still having trouble understanding it.
This code is supposed to implement a General Tree. Single_List and Single_Node classes are also available for use in implementation.
template <class Object>
class General_tree {
private:
Object element; // the stored in the node
Single_list< General_tree<Object> * > children;
// a linked list of pointers to general trees
public:
Object retrieve() {
return element;
}
// ...
};
Can someone tell me what one instance of this class will consist of?
I think it will consist of
[element value in node made by Single_Node] ----->
/ next pointer (part of Single_list class)
/
/ children pointer to another such instance of General_Tree
V
Then these instances can be combined to form a tree... I am still getting used to Object Oriented Design I guess so please let me know if this reasoning and interpretation is correct?
thanks!
The tree object is really a node in the tree, where children points to the nodes at the next level, which will have pointers to their children, etc.
Together they form a subtree (or the whole tree, if it is the root node).
Related
I have a tree-like data structure that I've set up like this:
class Root; // forward declaration
class Tree {
public:
void addChildren(Root &r, ...) { childA = r.nodeSpace.allocate(); ... }
// tons of useful recursive functions here
private:
Tree *childA, *childB, *childC;
Tree *parent;
int usefulInt;
};
class Root : public Tree {
friend class Tree; // so it can access our storage
public:
private:
MemoryPool<Tree> nodeSpace;
};
I really like this structure, because
I can call all the recursive functions defined on Tree on Root as well, without having to copy-paste them over.
Root owns the storage, so whenever it passes out of scope, that's how I define the tree as no longer being valid.
But then I realized a problem. Someone might inadvertently call
Tree *root = new Root();
delete root; // memory leak! Tree has no virtual destructor...
This is not an intended usage (any ordinary usage should have Root on the stack). But I am open to alternatives. Right now, to solve this, I have three proposals:
Add virtual destructor to Tree. I would prefer not doing this because of the overhead as the tree can have many, many nodes.
Do not let Root inherit from Tree but instead have it define its own Tree member. Creates a little indirection, not too terrible, can still call the tons of useful recursive functions in Tree by doing root.tree().recursive().
Forbid assignments like Tree *root = new Root();. I have no idea if this is even possible or discouraged or encouraged. Are there compiler constructs?
Something else?
Which one of these should I prefer? Thank you very much!
The root node class (or any other node class) should not be an interface class. Keep it private and then inheritance without dynamic polymorphism (virtual) is not dangerous because the user will never see it.
Forbid assignments like Tree *root = new Root();. I have no idea if this is even possible or discouraged or encouraged. Are there compiler constructs?
This would be done by having Root inherit from Tree as a private base class.
So I am in process of coding class for some graph structure (suffix tree), and I encountered this difficult thing: a node should have pointers, one pointing on its parent, and also a set of pointers to its sons. I am using smart pointers to avoid errors with memory, and here is the thing: I write
class node {
...
std::shared_ptr<node> parent;
...
};
I guess there is a term for this thing. Like self-referencing, or whatever. When I wrote it, initialy i was confident, that there will be an error, but no it had been successfully compiled. I was curious, can i write something like that:
class some_class_2{
...
std::vector<some_class_2> some_vector;
std::string string_;
some_class() {
string_ = "lol";
some_vector = std::vector<some_class>(10);
}
};
Its appeared that the answer on this question is yes. So when i launched the test programm which had been succesfully compiled, of course it wouldn't stop, maybe i waited not enough and it should throw me some memory related error.
So the question is, how you should handle with this kind of things in c++? Isn't it strange that those things allowed in c++? Is it normal to put std::shatre_ptr inside some_class? How to write safe code, where errors like in some_class_2 are avoided, and what is the best way to
represent graph structure?
If the language did not allow any use of node inside the definition of node, then there would be no way to create linked data structures such as lists and trees. In order for the language to be useful, it has to allow such constructs as:
struct node {
int key;
node* next;
};
On the other hand, the language cannot allow this:
struct node {
int key;
node next;
};
because then a node object would contain an infinite nested sequence of node objects and be infinitely large.
The way the language deals with this is to allow members of classes only to be complete types. A complete type's size is known. A class type is not complete until its full definition has been seen. So node is not complete inside its own definition, so you cannot put a node member inside a node object. But node* is complete even when node is not complete yet.
Some standard library templates can be used with complete types. The smart pointers, std::unique_ptr<T>, std::shared_ptr<T>, and std::weak_ptr<T>, are allowed to have incomplete T, since they have pointer semantics. However, std::vector does not allow its template parameter to be incomplete, and the result is undefined behaviour. The way to avoid this is to just not write it (it's not that hard).
I need to implement a custom tree class (using C++). Throughout my work I've seen many tree implementations. Some implemented a "super Node" class which was exposed to the user. An instance of which (root node) acted as the tree. Some exposed a tree class, which utilized a node class to construct a tree. Some used the node class as a pure data struct, leaving functionality such as tree construction to the tree class. Others put the construction - like node.Split(), into the node class.
Say you needed to design a binary tree (like a KD-tree). What would be the "best" approach from OOP perspective. Have node class just contain the data, or the logic to split itself into children? How much logic in general should a node class contain?
Thanks ahead for constructive input!
Here's one OOP rule you should always follow,
Every class represents an entity. Classes have properties and methods
i.e. the attributes of the entities and it's behaviour
So you need to follow your understanding of the scenario.
Here's how I look at a node.
It has some data, a right node reference and a left node reference. I don't think a node should be able to do anything except provide you with the data so I would write a node class something like this:
class Node
{
public:
int Data; // yeah, you would obviously use templates, so it's not restricted to a particular type
Node* Left;
Node* Right;
// also you can write constructors and maybe some sort of cast operator overload to be able to make the
// we could also make it return the subtree itself
getRightSubTree(){ return Tree(*Right); }
getLeftSubTree(){ return Tree(*Left); }
};
A Tree should be like this then.
class Tree
{
private:
Node root;
public:
Tree(Node t):root(t){} // every tree should have a root. Cannot be null.
// since the root node will be able to handle the tree structure, now we'll need the necessary methods
void addNode(Node n){
// code here
}
....
getSubTree(int data){
// check if node with that data exists and all
...
Node n = getNode(data);
return Tree(n);
}
};
Okay so I think you've got an idea now. It's all about how you look at the system.
I've been trying to implement a heap into my program. It seems to me that heaps are the same as binary trees. Is this the case with all heaps such as min heap and max heap since all that is being done is a traversal through the tree putting the largest/smallest node to the top?
Also, I've read that using 1-D arrays are only beneficial when we have a complete binary tree. If we don't have a complete binary tree, it would be more beneficial to use class that is a friend class to another? Why is that? Such as:
template<class T> class BT; // forward declartion -> added at edit
template<class T>
class BTNode{
friend class BT<T>; // not sure why we need two classes
private:
T data;
BTNode<T> *leftChild; // what is the benefit of making a object Node?
BTNode<T> *rightChild;
};
template<class T>
class BT{
private:
BTNode<T> *root; // what is the benefit of having this root in another class?
};
Thank you in advance.
There's a perfectly good heap implementation in the standard library; you should take a look at it (but it is a useful learning exercise to write your own, too.)
A binary heap is a binary tree, but it is stored efficiently as a vector. The links are implicit. That is to say, the children of the node at position i (zero-based) are at 2i+1 and 2i+2. (At most one node in a heap has only one child.) That means that you don't actually have to store links, so in the case of small data objects (like integers), you're saving at least two-thirds of the needed space.
Wikipedia has a nice article on binary heaps (the kind you normally store in vectors), but it also has a number of articles on other types of heaps.
I need a little assistance with high level design of this program.
I am manually creating class objects based on an XML description. It has nodes which define settings of a piece of hardware. The trouble is the nodes in the XML can simply point to other nodes by name. To be able to find the address of these node objects quickly based on name, I am using a map. This is simplified view:
class XMLfile
{
public:
Node* GetNode(const string FeatName); //Searches through "nodes" map to get pointer to Node
private:
map<std::string, Node*> nodes;
};
Then I define nodes as follows:
class Node
{
public:
virtual int GetValue();
virtual int Load(XML_type);
};
Then depending on the exact "type" of node, I create a few derived classes with additional variables.
class Integer: public Node
{
int IntegerSpecificVar;
int GetValue();
int Load(XML_type);
private:
int Value;
string p_Value;
};
The XML can be one of the two:
<Value>5</value> Which my object load will load 5 into int Value.
or
<p_Value>NodeName</p_Value> Which my object loader will load the string into p_Value.
Depending on the object in the XML, the GetValue() returns the int Value, or a pointer to a string with a different nodename. If its a pointer, I need to get the pointer to that node and then call GetValue on that object. What I really want to do is call XML::GetNode(nodename") but this is out of context.
One idea to get my Node objects access to that map is to create the class Node which is derived from the XMLfile:
class Node: public XMLfile
then I get circular references since it has not loaded yet. If I switch the order between class Node and class XMLfile, then XMLfile doesn't know what a Node class/type is. Note this is all in one big file for now.
IF anyone can offer general suggestions how to better arrange this it would be appreciated.
It's bad idea to think of a Node as an specified case of XMLfile, so don't derive one from the other. Inheritance means the relationship of A 'is-a' B.
Quick and possibly dirty solutions:
make the map a parameter of GetValue, or
store a (const) reference or pointer to the map inside Node.