N
nandor.sieben
I'm working on a project analyzing a game and I am in need of a tree
template library. I found a few implementations on the web but all of
them were too complicated for me to understand. I wrote something on my
own. I used an STL vector to store children of a node. My major concern
is memory leak. I am not sure if doing a pop_back() to cut a tree
branch would result in memory leak. I would appreciate some advise on
this. Also is there a similarly simple but well tested implementation
out there?
Nandor
#include <vector>
#include <string>
using namespace std;
// data and the arrows
template < class T > struct Tnode_
{
T data;
vector < Tnode_ > ch;
Tnode_ *parentp;
};
// a Tnode is a pointer to a Tnode_ with member functions
template < class T > struct Tnode
{
Tnode_ < T > *p;
// get the data value of the node
T get ()
{
return p->data;
}
// set the data value of the node
void set (T a)
{
p->data = a;
}
// the n-th child node
Tnode child (int n)
{
Tnode node2;
node2.p = &p->ch[n];
return node2;
}
// add a child node
void add_child ()
{
Tnode_ < T > node_;
node_.parentp = p;
p->ch.push_back (node_);
}
// number of children
int Nchildren ()
{
return p->ch.size ();
}
// the first child node
Tnode begin ()
{
Tnode node2;
node2.p = &p->ch.front ();
return node2;
}
// the last child node
Tnode end ()
{
Tnode node2;
node2.p = &p->ch.back ();
return node2;
}
// the parent node
Tnode parent ()
{
Tnode node2;
node2.p = p->parentp;
return node2;
}
T *operator & ()
{
return &p->data;
}
};
// make a tree head and set node to this head
template < class T > void
make_head (Tnode < T > &node)
{
node.p = new Tnode_ < T >;
node.p->parentp = NULL;
}
// print the tree
template < class T > void
travel (Tnode < T > node, int level)
{
for (int i = 0; i < level; i++)
cout << " :";
cout << ". ";
cout << node.get () << "\n";
for (int i = 0; i < node.Nchildren (); i++)
travel (node.child (i), level + 1);
}
main ()
{
Tnode < string > head, node;
make_head (head);
node = head;
node.set ("one");
node.add_child ();
node.add_child ();
node = node.end ();
node.set ("three");
node = node.parent ();
node = node.begin ();
node.set ("two");
node.add_child ();
node.add_child ();
node.add_child ();
node = node.begin ();
node.set ("apple");
node = node.parent ();
node = node.end ();
node.set ("peach");
node = node.parent ();
node = node.child (1);
node.set ("banana");
node.add_child ();
node = node.begin ();
node.set ("cherry");
travel (head, 0);
cout << "\n";
cout << node.get () << "\n";
*&node = "CHERRY";
cout << *&node << "\n";
}
template library. I found a few implementations on the web but all of
them were too complicated for me to understand. I wrote something on my
own. I used an STL vector to store children of a node. My major concern
is memory leak. I am not sure if doing a pop_back() to cut a tree
branch would result in memory leak. I would appreciate some advise on
this. Also is there a similarly simple but well tested implementation
out there?
Nandor
#include <vector>
#include <string>
using namespace std;
// data and the arrows
template < class T > struct Tnode_
{
T data;
vector < Tnode_ > ch;
Tnode_ *parentp;
};
// a Tnode is a pointer to a Tnode_ with member functions
template < class T > struct Tnode
{
Tnode_ < T > *p;
// get the data value of the node
T get ()
{
return p->data;
}
// set the data value of the node
void set (T a)
{
p->data = a;
}
// the n-th child node
Tnode child (int n)
{
Tnode node2;
node2.p = &p->ch[n];
return node2;
}
// add a child node
void add_child ()
{
Tnode_ < T > node_;
node_.parentp = p;
p->ch.push_back (node_);
}
// number of children
int Nchildren ()
{
return p->ch.size ();
}
// the first child node
Tnode begin ()
{
Tnode node2;
node2.p = &p->ch.front ();
return node2;
}
// the last child node
Tnode end ()
{
Tnode node2;
node2.p = &p->ch.back ();
return node2;
}
// the parent node
Tnode parent ()
{
Tnode node2;
node2.p = p->parentp;
return node2;
}
T *operator & ()
{
return &p->data;
}
};
// make a tree head and set node to this head
template < class T > void
make_head (Tnode < T > &node)
{
node.p = new Tnode_ < T >;
node.p->parentp = NULL;
}
// print the tree
template < class T > void
travel (Tnode < T > node, int level)
{
for (int i = 0; i < level; i++)
cout << " :";
cout << ". ";
cout << node.get () << "\n";
for (int i = 0; i < node.Nchildren (); i++)
travel (node.child (i), level + 1);
}
main ()
{
Tnode < string > head, node;
make_head (head);
node = head;
node.set ("one");
node.add_child ();
node.add_child ();
node = node.end ();
node.set ("three");
node = node.parent ();
node = node.begin ();
node.set ("two");
node.add_child ();
node.add_child ();
node.add_child ();
node = node.begin ();
node.set ("apple");
node = node.parent ();
node = node.end ();
node.set ("peach");
node = node.parent ();
node = node.child (1);
node.set ("banana");
node.add_child ();
node = node.begin ();
node.set ("cherry");
travel (head, 0);
cout << "\n";
cout << node.get () << "\n";
*&node = "CHERRY";
cout << *&node << "\n";
}