0

I'm writing an implementation of a CART tree at the moment, which is binary tree used in machine learning. It is trained recursively as sketched in the following code:

struct Node
{
    Node * parent;
    Node * left;
    Node * right;
};

void train(Node* node)
{
    //perform training algorithm on node

    train(node->left);
    train(node->right);
}

Now assume I restrict the number of traing iterations to a chosen value, say nTraining=4.

Then, by unrolling the recursive function calls, I expect that only the left branch is evolved. So the first four calls are:

    train(node);
    train(node->left);
    train(node->left->left);
    train(node->left->left->left);
    //only now train(node->left->left->right); would follow 

which gives a completely unbalanced tree looking like

          O
         / \
        O   O
       / \
      O   O
     / \
    O   O
   / \
  O   O

Can anybody please suggest a way by which I can further use the recursive training approach and still obtain a balanced tree?

davidhigh
  • 14,652
  • 2
  • 44
  • 75

1 Answers1

2

I'd say, don't use recursion (DFS). Use BFS, that is queue instead, so the tree is traversed level by level:

std::queue<Node*> q;
Node* root;
q.push(root);
for (int i = 0; i < nTraining; ++i) {
    Node* node = q.front();
    q.pop();
    train(node);
    q.push(node->left);
    q.push(node->right);
}
Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • thanks for the good answer, I'll probably have to switch to this approach (otherwise I'd have to use stopping rules which consider not only the single node, but rather the whole tree). – davidhigh Jan 08 '16 at 23:31
  • just for completeness: the `std::queue` thing is only to forbid training later nodes, isn't it? One could use as well a `std::deque` and pop it repeatedly? – davidhigh Jan 08 '16 at 23:33
  • 1
    @davidhigh yes, you could use `std::deque` with `push_back` and `pop_front`. In fact, `std::queue` is a wrapper around `std::deque` by default. – Anton Savin Jan 09 '16 at 02:29