Task

Implement a binary tree where each node carries an integer,   and implement:

   pre-order,
   in-order, 
   post-order,     and 
   level-order   traversal. 


Use those traversals to output the following tree:

         1
        / \
       /   \
      /     \
     2       3
    / \     /
   4   5   6
  /       / \
 7       8   9

The correct output should look like this:

preorder:    1 2 4 7 5 3 6 8 9
inorder:     7 4 2 5 1 8 6 9 3
postorder:   7 4 5 2 8 9 6 3 1
level-order: 1 2 3 4 5 6 7 8 9



See also

   Wikipedia article:   Tree traversal.


BinaryTreeNode = Struct.new(:value, :left, :right) do
  def self.from_array(nested_list)
    value, left, right = nested_list
    if value 
      self.new(value, self.from_array(left), self.from_array(right))
    end
  end
 
  def walk_nodes(order, &block)
    order.each do |node|
      case node
      when :left  then left && left.walk_nodes(order, &block)
      when :self  then yield self
      when :right then right && right.walk_nodes(order, &block)
      end
    end
  end
 
  def each_preorder(&b)  walk_nodes([:self, :left, :right], &b) end
  def each_inorder(&b)   walk_nodes([:left, :self, :right], &b) end
  def each_postorder(&b) walk_nodes([:left, :right, :self], &b) end
 
  def each_levelorder
    queue = [self]
    until queue.empty?
      node = queue.shift
      yield node
      queue << node.left if node.left
      queue << node.right if node.right
    end
  end
end
 
root = BinaryTreeNode.from_array [1, [2, [4, 7], [5]], [3, [6, [8], [9]]]] 
 
BinaryTreeNode.instance_methods.select{|m| m=~/.+order/}.each do |mthd|
  printf "%-11s ", mthd[5..-1] + ':'
  root.send(mthd) {|node| print "#{node.value} "}
  puts
end