I want to create tree in C++.
I could compile the code without errors or warnings, but i don't get an output.
I think error is in inorder fn, but don't know how to remove this.
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
struct tree
{
int data;
struct tree * left;
struct tree * right;
};
typedef struct tree * TREE;
TREE maketree(int x)
{
TREE tree = (TREE)malloc(sizeof(tree));
if(tree == NULL)
{
return NULL;
}
tree->left = tree->right = NULL;
tree->data = x;
return tree;
}
void setleft(TREE tree,int x)
{
if(tree == NULL || tree->left != NULL)
{
cout<<"\t Error !! Inserting New Node At Left Side !\n";
}
else
{
tree->left = maketree(x);
}
}
void setright(TREE tree,int x)
{
if(tree == NULL || tree->right != NULL)
{
cout<<"\t Error !! Inserting New Node At Right Side !\n";
}
else
{
tree->right = maketree(x);
}
}
void inorder(TREE root)
{
if(root != NULL)
{
TREE left=root->left;
TREE right=root->right;
inorder(left);
cout<<root->data;
inorder(right);
}
}
void main()
{
clrscr();
TREE root = NULL,child,parent;
int i,j = 1;
cout<<"Root Of Binary Search Tree :- ";
cin>>i;
root = maketree(i);
cout<<"\n\n";
while(i)
{
cout<<j<<" Node Value:- ";
cin>>i;
if(i < 0)
{
break;
}
parent = child = root;
while((i != parent->data) && (child != NULL))
{
parent = child;
if(i < parent->data)
{
child = parent->left;
}
else
{
child = parent->right;
}
}
if(i == parent->data)
{
cout<<"\t Value "<<i<<" Already Present In BST !!\n";
}
else if(i < parent->data)
{
setleft(parent,i);
}
else
{
setright(parent,i);
}
j++;
}
inorder(root);
getch();
}
If you want to write in C++ then write in C++. Use constructors and destructors and class methods. Possibly make your data members private. And use new rather than malloc and your destructors will probably want to delete (the child nodes of the tree).
What you have written is in C other than you've incorporated the worst feature of C++, iostream, and that in its old deprecated non-standard version.
This looks like some school exercise.
I also can't see anywhere where you free the data you have allocated with malloc.
Your sorting logic should be in a tree-based function, not main.
Your "error" may be the lack of whitespace in the output, but I don't know.
It's legal but not good practice to use tree as both a data-type (it's a struct, which in C++ does not need qualifying with struct) and a variable (for which it is often being used).
Ok, now a bit of code, mostly based on yours.
class tree
{
tree * left;
tree * right;
int value;
public:
explicit tree( int v );
~tree();
bool insert( int v );
void print( std::ostream& ) const;
private:
tree( const tree& );
tree& operator=( const tree& );
};
tree::tree( int v ) :
left( NULL ),
right( NULL ),
value( v )
{
}
tree::~tree()
{
delete right;
delete left;
}
bool tree::insert( int v )
{
// inserts v in the correct place in the tree, returns true
// if it inserted or false if it already exists
// I want you to fill in the detail for this function
}
void tree::print( std::ostream& os ) const
{
// prints the tree
if( left )
{
left->print( os );
}
os << value << '\n';
if( right )
{
right->print( os );
}
}
There, I have left one function for you to implement. You do not need to implement the private copy constructor or assignment operator.
Also implement main(). Note that there is no need to implement the tree in main on the heap (with new). Implement it on the stack.
main() will read in the numbers, insert them in to the tree calling its insert() method and then at the end print the tree, passing std::cout as a parameter.
You need to #include <iostream> (not iostream.h) and it will work.
Related
I have been trying to get this function working for the longest time now. It is part of an assignment for an online course, but it seems no matter what I submit, the function fails for both the empty child test and the left child test. See code below. The main() function is deliberately commented out. Any info./input is much appreciated.
// C++ binary trees and stuff;
//
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
class BST
{
public:
int data;
BST *left;
BST *right;
//BST *root;
// BST() constructor
BST (int num)
{
data = num;
left = nullptr;
right = nullptr;
root = nullptr;
}
// constructors for root node(s), initializing as root when no values exist yet;
BST() : root (nullptr){}
BST (BST *rootNode) : root(rootNode){}
void insert (int value)
{
BST *newNode = new BST();
newNode = root;
if (root == nullptr)
{
root = new BST (value);
}
else
{
root->data = value;
}
// check if newNode's value equals the passed-in value:
if (value == root->data)
{
//cout << "\nWarning! Value already exists in tree, so nothing will be done.\n";
return;
}
// check if value is < or > newNode's value:
if (value <= root->data)
{
if (root->left == nullptr)
{
// make a new node as the left child of this node,
root->left = new BST(value);
}
else
{
// recursively call insert() on tree's left side,
root->left->insert(value);
}
}
else
{
if (root->right == nullptr)
{
// make a new node as the right child of this node,
root->right = new BST(value);
}
else
{
// recursively call insert() on tree's right side,
root->right->insert(value);
}
}
}
public:
BST *root;
};
/*
int main (int argc, char *argv[])
{
//...insert code here,
// create nodes,...
BST rootNode(5);
BST leftNode(4);
BST rightNode(6);
// connect the nodes to the tree via rootNode.left and rootNode.right,..
rootNode.left = &leftNode;
rootNode.right = &rightNode;
printf ("\nData (root) value = %i, rootNode.left = %i, and rootNode.right = %i\n",
rootNode.data, rootNode.left->data, rootNode.right->data);
cout << "\n\nHello, Solar System!\n";
return 0;
}
*/
Okay, here's my suggestion. You need to reformat your code. You need two classes. You need a BST, and you need a Node. The various methods to add/remove/traverse are part of the BST class. Nodes are just Nodes.
So:
class BST_Node {
public:
int value;
BST_Node * left = nullptr;
BST_Node * right = nullptr;
// Define constructors, etc.
};
class BST {
public:
BST_Node * root = nullptr;
BST_Node * insert(int value);
void insertNode(BST_Node *node);
void insertNodeBelow(BST_Node *nodeToInsert, BST_Node *startingNode);
};
BST_Node * BST::insert(int value) {
BST_Node * node = new BST_Node(value);
insertNode(node);
return node;
}
void BST::insertNode(BST_Node *node) {
if (node == nullptr) {
return;
}
if (root == nullptr) {
root = node;
}
else {
insertNodeBelow(node, root);
}
}
void BST::insertNodeBelow(BST_Node *node, BST_Node *startingNode) {
if (node == nullptr || startingNode == nullptr) {
return;
}
if (node->value < startingNode->value) {
if (startingNode->left != nullptr) {
insertNodeBelow(node, startingNode->left);
}
else {
startingNode->left = node;
}
}
else {
if (startingNode->right != nullptr) {
insertNodeBelow(node, startingNode->right);
}
else {
startingNode->right = node;
}
}
}
How this works... First, the logic of how to store nodes is in BST. Nodes don't care. Second, I made methods for either inserting a value or a node. Because I think that's handy. That should be fairly easy to understand.
The root node can be null, if so, then your inserted node is now root. Otherwise it calls the recursive insertion function. Now, you could simplify this a little, but I didn't want to get too clever.
So it's simple. We look to see where it belongs relative to the point we're at (initially the root). Either we go into the left branch or the right branch. But that branch could be empty, so you just plop it right in. If it's not empty, then you recurse.
I didn't test it.
#include<iostream>
using namespace std;
class tree
{
public:
int data;
tree *left;
tree *right;
tree* add_left(int data)
{
tree *t = new tree;
left = t;
t->left = NULL;
t->right = NULL;
t->data = data;
return t;
}
tree* add_right(int data)
{
tree *t = new tree;
right = t;
t->left = NULL;
t->right = NULL;
t->data = data;
return t;
}
void preorder()
{
if(left==NULL && right==NULL)
cout<<data<<" ";
else
{
cout<<data<<" ";
left->preorder();
right->preorder();
}
}
};
int main()
{
tree *a = new tree;
a->data = 10;
tree *t = a->add_left(15);
tree *b = a->add_right(20);
tree *ne = t->add_left(30);
a->preorder();
return 0;
}
It just prints
10 15 30
and then segmentation error.
It is a binary tree. Add left and right adds nodes to the left and right side of the tree respectively.
The preorder should be 10 15 30 20, but for some reason, it does not print 20.
The logic of the function id incorrect. It can be called when the current pointer is equal to nullptr that is when either left pointer or right pointer is a null-pointer.
Rewrite the function the following way
void preorder() const
{
cout << data << " ";
if ( left ) left->preorder();
if ( right ) right->preorder();
}
If to call this member function for your tree then the output will be
10 15 30 20
Pay attention to that the function is declared with the qualifier const because it does not change the tree.
A more flexible function definition can look the following way
std::ostream & preorder( std::ostream &os = std::cout ) const
{
os << data << " ";
if ( left ) left->preorder();
if ( right ) right->preorder();
return os;
}
In this case you will be able to write the list into a file.
You code crashes because right is null while you calls preorder() on it, change if(left==NULL && right==NULL) to if(left==NULL || right==NULL) or other checks to avoid a null pointer dereference.
Change your tree::preorder method like this:
void preorder()
{
cout<<data<<" ";
if(left)
{
left->preorder();
}
if(right)
{
right->preorder();
}
}
I recently finished implementing a Binary search tree for a project I was working on. It went well and I learned a lot. However, now I need to implement a regular Binary Tree... which for some reason has me stumped.
I'm looking for a way to do my InsertNode function..
normally in a BST you just check if data < root then insert left and vice versa. However, In a normal Binary tree, it is just filled from left to right, one level at a time..
could anyone help me implement a function that just adds a new Node to the Binary tree from left to right in no specific order?
Here's my Insert for a BST:
void Insert(Node *& root, int data)
{
if(root == nullptr)
{
Node * NN = new Node;
root = NN;
}
else
{
if(data < root->data)
{
Insert(root->left, data);
}
else
{
Insert(root->right, data);
}
}
}
I am aware of the fact that this is a question posted some time ago, but I still wanted to share my thoughts on it.
What I would do (since this indeed is not very well documented) is use a Breadth-First-Search (using a queue) and insert the child into the first null I encounter. This will ensure that your tree will fill up the levels first before it goes to another level. With the right number of nodes, it will always be complete.
I haven't worked that much with c++, so to be sure it was correct I did it in Java, but you get the idea:
public void insert(Node node) {
if(root == null) {
root = node;
return;
}
/* insert using Breadth-first-search (queue to the rescue!) */
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
while(true) {
Node n = queue.remove();
if(!n.visited) System.out.println(n.data);
n.visited = true;
if(n.left == null) {
n.left = node;
break;
} else {
queue.offer(n.left);
}
if(n.right == null) {
n.right = node;
break;
} else {
queue.offer(n.right);
}
}
}
Javascript implementation (copy-paste ready for your web console):
ES6 implementation (newer javscript syntax with class keyword)
class BinaryTree {
constructor(value){
this.root = value;
this.left = null;
this.right = null;
}
insert(value){
var queue = [];
queue.push(this); //push the root
while(true){
var node = queue.pop();
if(node.left === null){
node.left = new BinaryTree(value);
return;
} else {
queue.unshift(node.left)
}
if(node.right === null){
node.right = new BinaryTree(value);
return;
} else {
queue.unshift(node.right)
}
}
}
}
var myBinaryTree = new BinaryTree(5);
myBinaryTree.insert(4);
myBinaryTree.insert(3);
myBinaryTree.insert(2);
myBinaryTree.insert(1);
5
/ \
4 3
/ \ (next insertions here)
2 1
Pseudoclassical pattern implementation
var BinaryTree = function(value){
this.root = value;
this.left = null;
this.right = null;
}
BinaryTree.prototype.insert = function(value){
//same logic as before
}
With a few modifications to your code, I hope this should help :
Node * Insert(Node * root, int data)
{
if(root == nullptr)
{
Node * NN = new Node();
root = NN;
root->data = data;
root->left = root ->right = NULL;
}
else
{
if(data < root->data)
{
root->left = Insert(root->left, data);
}
else
{
root->right = Insert(root->right, data);
}
}
return root;
}
Hence , this function returns the root node of the updated BST.
I took bknopper code, modified a little bit and translated to C++. As he stated, surprisingly, this is not well documented.
Here is the node structure and the insert function:
struct nodo
{
nodo(): izd(NULL), der(NULL) {};
int val;
struct nodo* izd;
struct nodo* der;
};
void inserta(struct nodo** raiz, int num)
{
if( !(*raiz) )
{
*raiz = new struct nodo;
(*raiz)->val = num;
}
else
{
std::deque<struct nodo*> cola;
cola.push_back( *raiz );
while(true)
{
struct nodo *n = cola.front();
cola.pop_front();
if( !n->izd ) {
n->izd = new struct nodo;
n->izd->val = num;
break;
} else {
cola.push_back(n->izd);
}
if( !n->der ) {
n->der = new struct nodo;
n->der->val = num;
break;
} else {
cola.push_back(n->der);
}
}
}
}
You call it this way:
inserta(&root, val);
Being root a pointer to node struct and val the integer value you want to insert.
Hope it helps someone.
You should try using a recursive approach such as x = new (x), if you know what that means. This way, you don't really have to worry about the root node. I am going to write some pseudocode for you:
//public function
add(data){
root = add(data, root)
}
//private helper function
Node add(data, currentNode){
if(currentNode = 0)
return new Node(data)
if(data less than currentNode's data)
currentNode.left = add(data, currentNode.left)
if(data more than currentNode's data)
currentNode.right = add(data, currentNode.right)
return currentNode
}
I made a tutorial regarding the implementation of a BST in C++, here
Just a simple BST to print numbers inorder. Couldn't figure out what I did wrong.
#include <iostream>
using namespace std;
class bst {
private:
bst* root;
bst* left;
bst* right;
int value;
public:
bst(const int& numb) : root(NULL), left(NULL), right(NULL) {
value = numb;
}
void insert(const int& numb) {
if (numb < value) {
if (left == NULL) {
left = new bst(numb);
left->root = left;
} else {
left->insert(numb);
}
} else if (numb > value) {
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
} else if (numb == value) {
cout << "duplicated value" << endl;
}
}
void inorder() {
if (left == NULL) cout << value << endl;
else left->inorder();
right->inorder();
}
};
int main() {
bst tree(5);
tree.insert(7);
tree.insert(1);
tree.insert(3);
tree.insert(2);
tree.insert(9);
tree.insert(10);
return 0;
}
Line 29 should read:
right->insert(numb);
where it currently reads:
left->insert(numb);
I highly recommend looking into gdb for solving situations like this.
inorder() should be:
if (left != NULL) left->inorder();
cout << value << endl;
if (right != NULL) right->inorder();
I assume the rest are correct.
Logic errors throughout.
Crash is here:
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
The else case shold use right, not left.
At least as I see it, your fundamental design is flawed. Although I realize many text books (and such) describe a tree as a recursive structure where each node has two sub-trees, I've never found that a very good way to design the code.
At least in my experience, in actual code, you're (much) better off separating the notion of a node in the tree from the notion of an entire tree. Only the tree should be visible to the outside world; node should be hidden away inside the tree, invisible to the outside world.
class bst {
class node {
int value;
node *left;
node *right;
// ...
};
// ...
node *root;
};
I'd then split insert into two pieces: a public function that takes a value, and just forwards to the second function with the root as the starting point. The second actually traverses the three and inserts the new item:
// public interface:
void insert(int v) {
insert(new node(v), root);
}
// private workhorse:
void insert(node *n, node *&pos) {
if (pos == NULL)
pos = n;
else if (n->value < pos->value)
insert(n,pos->left);
else if (n->value > pos->value)
insert(n,pos->right);
else
// duplicate value.
}
Likewise, inorder gets split into a public and private pair, with the public providing only an interface, and the private one doing all the real work:
// public interface:
void inorder() {
inorder(root);
}
// private worker
void inorder(node *n) {
if (n==NULL)
return;
inorder(n->left);
std::cout << n->value << endl;
inorder(n->right);
}
For what it's worth: yes, I have tested this code and it does work at least with the input you used in you main. It does have shortcomings though. For example, both insert and inorder traverse the tree recursively, so a large, badly imbalanced tree could lead to stack overflow. It's fairly easy to do insertion iteratively, but for real use you usually just switch to some sort of balanced tree instead.
I am really stuck, I'm getting an error at "CTree.add(num);" saying 'CTree' is undeclared, which doesn't make sense because I initialized it in tree.h?
The program is supposed to prompt the user, the user enters a command (i.e. "add 3", only 0-9 integers) and then I want it to insert that number into the tree.
//File: tree.h
class CTree
{
private:
CTree* m_pLeft;
CTree* m_pRight;
CTree* m_pRoot;
int m_nData;
public:
CTree();
bool isEmpty() const { return m_pRoot; }
bool search(int);
void print_inorder();
void inorder(CTree*);
void Add(int);
void remove(int);
void height();
};
//File: CTree.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
CTree::CTree()
{
m_pRoot=NULL;
}
bool CTree::search(int x)
{
if(x==m_nData) return true;
if(x < m_nData){ //go left
if(m_pLeft != NULL) //if possible
return m_pLeft->search(x);
}
else //go right
if(m_pRight != NULL) //ifpossible
return m_pRight->search(x);
return false;
}
void CTree::Add(int x)
{
CTree* t = new CTree;
CTree* parent;
t->m_nData = x;
t->m_pLeft = NULL;
t->m_pRight = NULL;
parent = NULL;
if(isEmpty()) m_pRoot = t;
else
{
//insert leaf nodes
CTree* leaf;
leaf = m_pRoot;
// find parent
while(leaf)
{
parent = leaf;
if(t->m_nData > leaf->m_nData)
leaf = leaf->m_pRight;
else
leaf = leaf->m_pLeft;
}
if(t->m_nData < parent->m_nData)
parent->m_pLeft = t;
else
parent->m_pRight = t;
}
}
void CTree::remove(int x)
{
bool found = false;
if(isEmpty())
{
cout<< "Tree is empty!" <<endl;
return;
}
CTree* current;
CTree* parent;
current = m_pRoot;
while(current != NULL)
{
if(current->m_nData == x)
{
found = true;
break;
}
else
{
parent = current;
if(x > current->m_nData) current = current->m_pRight;
else current = current->m_pLeft;
}
}
if(!found)
{
cout<< "Not found!" <<endl;
return;
}
// Node with single child
if((current->m_pLeft == NULL && current->m_pRight != NULL)|| (current->m_pLeft != NULL&& current->m_pRight != NULL))
{
if(current->m_pLeft == NULL && current->m_pRight != NULL)
{
if(parent->m_pLeft == current)
{
parent->m_pLeft = current->m_pRight;
delete current;
}
else
{
parent->m_pRight = current->m_pRight;
delete current;
}
}
else // left child present, no right child
{
if(parent->m_pLeft == current)
{
parent->m_pLeft = current->m_pLeft;
delete current;
}
else
{
parent->m_pRight = current->m_pLeft;
delete current;
}
}
return;
}
//We're looking at a leaf node
if( current->m_pLeft == NULL && current->m_pRight == NULL)
{
if(parent->m_pLeft == current) parent->m_pLeft = NULL;
else parent->m_pRight = NULL;
delete current;
//Node with 2 children
// replace node with smallest value in right subtree
if (current->m_pLeft != NULL && current->m_pRight != NULL)
{
CTree* check;
check = current->m_pRight;
if((check->m_pLeft == NULL) && (check->m_pRight == NULL))
{
current = check;
delete check;
current->m_pRight = NULL;
}
else // right child has children
{
//if the node's right child has a left child
// Move all the way down left to locate smallest element
if((current->m_pRight)->m_pLeft != NULL)
{
CTree* lcurrent;
CTree* lcurrent_parent;
lcurrent_parent = current->m_pRight;
lcurrent = (current->m_pRight)->m_pLeft;
while(lcurrent->m_pLeft != NULL)
{
lcurrent_parent = lcurrent;
lcurrent = lcurrent->m_pLeft;
}
current->m_nData = lcurrent->m_nData;
delete lcurrent;
lcurrent_parent->m_pLeft = NULL;
}
else
{
CTree* tmp;
tmp = current->m_pRight;
current->m_nData = tmp->m_nData;
current->m_pRight = tmp->m_pRight;
delete tmp;
}
}
return;
}
}
}
void CTree::print_inorder()
{
inorder(m_pRoot);
}
void CTree::inorder(CTree* x)
{
if(x != NULL)
{
if(x->m_pLeft) inorder(x->m_pLeft);
cout<<" "<<x->m_nData<<" ";
if(x->m_pRight) inorder(x->m_pRight);
}
else return;
}
//File: main.cpp
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <locale>
#include <string>
#define PROMPT "bst> "
using namespace std;
int getNumber(string s)
{
int num;
for(int i; i<=s.length();i++)
{
if(isdigit(s[i]))
{
num= s[i]-48;
}
}
return num;
} // getNumber
bool process(const string& s, CTree* aTree)
{
bool mustquit=false;
int num;
istringstream iss(s);
do
{
string sub;
iss >> sub; //
if(sub=="add" || sub=="insert")
{
num=getNumber(s);
cout<<num<<endl;
aTree->Add(num);
}
else if(sub=="delete" || sub=="remove")
{
num=getNumber(s);
cout<<num<<endl;
}
else if(sub=="search" || sub=="find")
{
num=getNumber(s);
cout<<num<<endl;
}
else if(sub=="height")
{
//do stuff
}
else if (sub=="quit")
return mustquit;
//else cout<<"INPUT ERROR"<<endl;
} while (iss);
return mustquit;
}// process
int main(){
string input="";
CTree *myTree;
myTree = new CTree();
bool finished=false;
int i;
cout<<PROMPT;
while(!finished)
{
if(input!="")cout<<PROMPT;
getline(cin,input);
finished=process(input, myTree);
delete myTree;
}//while
return 0;
}
add is a non-static member function, which means you can only call it on an instance of CTree. e.g.
CTree myTree;
myTree.add(num);
You are aware that you need an instance of the class CTree to actually use it? You wrote the entire thing under the assumption that you're operating on an instance of a class. An actual tree, rather than a blueprint for it.
As the answer before me said, it's not a static function or class-level. A non-static method needs to be invoked on an instance so that a silent pointer this can be set to something meaningful, ie. the actual instance you're working with - in this case adding a node.
ADDENDUM
(everything below works without modifying your code, just an explicit answer to your question, to make it compile. From a "working standpoint", this program is far from complete. Some pieces don't even make sense, many variables are left unused or uninitialized (and then used). Let me elaborate further below.)
What you need to do is this add this in your main where the old process() call occured:
CTree myTree; // you could also add (), even though it's a default constructor
finished=process(input, myTree);
And modify the function process' argument list to include a reference to your tree which you wish to operate on. This is just one of the possibilities, you can also take a pointer etc. But a reference is cleaner:
bool process(const string& s, CTree& aTree)
Also, pay attention to compiler warnings. Good practice is to take care of all of them. And remember, this makes it compile, not work. It seems unfinished and rough around the edges.
And remember the difference between a class (an idea) and an instance (a manifestation of that idea). The technical details are not important right now, just make sure you have an instance to work with, as your class design intends. It seems to me that you don't have a grasp around how computer software works, how data and instructions that operate on it connect, especially from a viewpoint of memory. It's not enough for the computer to know what you want to do, it needs to know on what do you want the operations performed (which variables or objects or what-have-you). You can copy by value and return, do it in the main function, pass a reference or a pointer with an address so it can know where in memory is your object/instance located etc. If you're just experimenting, you could create a global instance. A lot of options.
Redeclaring everything doesn't carry over the changes that happen previously (since stuff goes out of scope). Nor does it make sense to call non-static member methods on the class level - and not even properly.
Hope it helps and happy coding. Keep at it, nothing worth doing is simple.
I think they are getting a little too technical for your level of experience. YourCTree class code creates what a CTree class is and how it behaves (a blueprint) but you actually have to tell your code to construct one and then have a way to reference it.
You can declare a stack variable instance like this:
CTree myTree;
This allocates the memory for your class and calls the constructor on entry into the function. You would then work with it by referencing the functions from the instance name using dot notation.
myTree.Add(4);
Or you can declare a pointer to a CTree and create a dynamic instance using the new operator
CTree *myTree;
myTree = new CTree();
Then you reference the tree using pointer notation:
myTree->Add(4);
if you do it that way you will need to delete the memory you allocated
delete myTree;
So in summary, a class definition of the kind you show here describes a class, but does not create one (allocate memory and setup pointers to the method code). This allows you to have many trees if your code logic requires them;
CTree directoryTree;
CTree fileTree;
CTree indexTree;
These would each have their own data ...
Good luck,