HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Printing out a binary tree level by level

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
levelprintingbinaryouttree

Problem

Below is my implementation for an interview question of printing a binary tree level by level. I've also included some methods for creating a binary tree from a vector in my solution. Please review my solution.

#include 
#include 
#include 
#include 
#include 

template  
struct Node
{
  T data;
  Node* left;
  Node* right;

  Node (T d, Node* l = nullptr, Node* r = nullptr) : data(d), left(l), right(r) {}
};

template
void deleteTree ( Node* n)
{
  if ( !n )
    return;
  deleteTree(n->left);
  deleteTree(n->right);
  delete n;
}

template 
void printBinaryTree (Node* n )
{
  std::unordered_map*> > m;
  printBinaryTree (n, m, 0);
  for ( auto& i : m )
  {
    std::cout data 
void printBinaryTree (Node* n, std::unordered_map*> >& m, int level )
{
  if (n)
  {
    ++level;
    printBinaryTree ( n->left ,m,level);
    printBinaryTree ( n->right,m,level);

    m[level].push_back(n);
  }
}

template 
auto buildBinaryTree (ItType start, ItType end) -> Node::value_type>*
{
  using T =typename std::iterator_traits::value_type;
  auto first = start;
  auto last = std::prev(end);

  if ( first > last ) // error case
    return nullptr;
  else if ( first * n = new Node(*mid);
    n->left = buildBinaryTree ( first, mid);
    n->right = buildBinaryTree ( mid+1, end);
    return n;
  }

  // equal
  return new Node(*first);
}

template  
Node* buildBinaryTree (std::vector& v)
{
  if  ( v.empty() )
   return nullptr; 

  std::sort(v.begin(), v.end());
  return buildBinaryTree (v.begin(), v.end()); 
}

int main()
{
  std::vector v { 1,2,3,4,5,6,7,8,9,10 };
  Node* root = buildBinaryTree ( v );
  printBinaryTree (root);
  deleteTree(root);
}

Solution

I got the following output:

Level 1: 5   Level 2: 2  8   Level 4: 4  7  10   Level 3: 1  3  6  9


Printing the layers in a non-deterministic order is probably undesirable behaviour. You used an unordered_map, which guarantees the order of neither its keys nor its values. To impose order on the values (the nodes of each level), you store a vector in the map, which complicates the data structure.

The traditional way to do a breadth-first traversal of a tree is to use a queue, and to work iteratively on elements of the queue rather than recursively on elements of the tree. Not only is this a less complex data structure than an unordered map of ints to vectors of nodes, it also stores nodes from no more than two levels of the tree at a time, rather than all nodes of the tree at once.

#include 
#include    // for std::pair

template 
void printBinaryTree(const Node *n) {
    if (nullptr == n) {
        return;
    }
    int level = 0;

    // Use a queue for breadth-first traversal of the tree.  The pair is
    // to keep track of the depth of each node.  (Depth of root node is 1.)
    typedef std::pair*,int> node_level;
    std::queue q;
    q.push(node_level(n, 1));

    while (!q.empty()) {
        node_level nl = q.front();
        q.pop();
        if (nullptr != (n = nl.first)) {
            if (level != nl.second) {
                std::cout data left,  1 + level));
            q.push(node_level(n->right, 1 + level));
        }
    }
    std::cout << std::endl;
}


As a final touch, pay attention to the const-correctness of the function's parameter.

Code Snippets

Level 1: 5   Level 2: 2  8   Level 4: 4  7  10   Level 3: 1  3  6  9
#include <queue>
#include <utility>   // for std::pair

template <typename T>
void printBinaryTree(const Node<T> *n) {
    if (nullptr == n) {
        return;
    }
    int level = 0;

    // Use a queue for breadth-first traversal of the tree.  The pair is
    // to keep track of the depth of each node.  (Depth of root node is 1.)
    typedef std::pair<const Node<T>*,int> node_level;
    std::queue<node_level> q;
    q.push(node_level(n, 1));

    while (!q.empty()) {
        node_level nl = q.front();
        q.pop();
        if (nullptr != (n = nl.first)) {
            if (level != nl.second) {
                std::cout << " Level " << nl.second << ": ";
                level = nl.second;
            }
            std::cout << n->data << ' ';
            q.push(node_level(n->left,  1 + level));
            q.push(node_level(n->right, 1 + level));
        }
    }
    std::cout << std::endl;
}

Context

StackExchange Code Review Q#35656, answer score: 8

Revisions (0)

No revisions yet.