// depth first -> get to leaves fast -> recursive
// breadth first ->    -> usually (always?) not recursive

// level 1: 8
// level 2: 4 12
// level 3: 2 6  14
// level 4: 1 3 5 7  13 15
// level 5: 4.5

template <class T>
void breadth_first_print(TreeNode<T>* root) {
  int counter = 1;
  if (root == NULL) return;
  // current = list of all nodes on a specific level
  std::list< TreeNode<T>* > current;
  current.push_back(root);
  // next = list of all nodes on the next level
  std::list< TreeNode<T>* > next;
  // print everything at this level (if there is anything at this level)
  while ( current.size() > 0 ) {  
    std::cout << "level " << counter << ": ";
    typename std::list<TreeNode<T>*>::iterator itr = current.begin();
    while ( itr != current.end() ) {
      TreeNode<T> *tmp = *itr;
      std::cout << tmp->value << " ";
      // if you find stuff for the next level, add it to that next level
      if (tmp->left != NULL) { next.push_back(tmp->left); }
      if (tmp->right != NULL) { next.push_back(tmp->right); }
      itr++;
    }
    // move on to the next level!
    current = next;
    next.clear();
    counter++;
    std::cout << std::endl;
  }
}
