binary tree -print the elements according to the level

12,442

Solution 1

You need to do a breadth first traversal of the tree. Here it is described as follows:

Breadth-first traversal: Depth-first is not the only way to go through the elements of a tree. Another way is to go through them level-by-level.

For example, each element exists at a certain level (or depth) in the tree:

    tree
      ----
       j         <-- level 0
     /   \
    f      k     <-- level 1
  /   \      \
 a     h      z  <-- level 2
  \
   d             <-- level 3

people like to number things starting with 0.)

So, if we want to visit the elements level-by-level (and left-to-right, as usual), we would start at level 0 with j, then go to level 1 for f and k, then go to level 2 for a, h and z, and finally go to level 3 for d.

This level-by-level traversal is called a breadth-first traversal because we explore the breadth, i.e., full width of the tree at a given level, before going deeper.

Solution 2

The traversal in your question is called a level-order traversal and this is how it's done (very simple/clean code snippet I found).

You basically use a queue and the order of operations will look something like this:

enqueue F
dequeue F
enqueue B G
dequeue B
enqueue A D
dequeue G
enqueue I
dequeue A
dequeue D
enqueue C E
dequeue I
enqueue H
dequeue C
dequeue E
dequeue H

For this tree (straight from Wikipedia):
enter image description here

Solution 3

The term for that is level-order traversal. Wikipedia describes an algorithm for that using a queue:

levelorder(root) 
  q = empty queue
  q.enqueue(root)
  while not q.empty do
    node := q.dequeue()
    visit(node)
    if node.left ≠ null
      q.enqueue(node.left)
    if node.right ≠ null
      q.enqueue(node.right)

Solution 4

BFS:

std::queue<Node const *> q;
q.push(&root);
while (!q.empty()) {
    Node const *n = q.front();
    q.pop();
    std::cout << n->data << std::endl;
    if (n->left)
        q.push(n->left);
    if (n->right)
        q.push(n->right);
}

Iterative deepening would also work and saves memory use, but at the expense of computing time.

Solution 5

If we are able to fetch the next element at same level, we are done. As per our prior knowledge, we can access these element using breadth first traversal.

Now only problem is how to check if we are at last element at any level. For this reason, we should be appending a delimiter (NULL in this case) to mark end of a level.

Algorithm: 1. Put root in queue.
2. Put NULL in queue.
3. While Queue is not empty
4. x = fetch first element from queue
5. If x is not NULL
6. x->rpeer <= top element of queue.
7. put left and right child of x in queue
8. else
9. if queue is not empty
10. put NULL in queue
11. end if
12. end while
13. return

#include <queue>

void print(tree* root)
{
  queue<tree*> que;
  if (!root)
      return;

  tree *tmp, *l, *r;
  que.push(root);
  que.push(NULL);

  while( !que.empty() )
  {
      tmp = que.front();
      que.pop();
      if(tmp != NULL)
      {
          cout << tmp=>val;  //print value
          l = tmp->left;
          r = tmp->right;
          if(l) que.push(l);
          if(r) que.push(r);
      }
      else
      {
          if (!que.empty())
              que.push(NULL);
      }
  }
  return;
}
Share:
12,442
Vijay
Author by

Vijay

http://theunixshell.blogspot.com/

Updated on September 15, 2022

Comments

  • Vijay
    Vijay over 1 year

    This question was asked to me in an interview:

    Binary tree

    lets say we have above binary tree,how can i produce an output like below

    2 7 5 2 6 9 5 11 4
    

    i answered like may be we can have a level count variable and print all the elements sequentially by checking the level count variable of each node. probably i was wrong.

    can anybody give anyidea as to how we can achieve that?

  • Vijay
    Vijay about 13 years
    do u have any resource explaining the breadth first traversal?