Please help with printing a Binary Tree in a nice-looking way

I've just learned about Binary Tree and so far I've understood how to build one or inserting into my tree.

Below is my Node struct
1
2
3
4
5
6
struct Node
{
	int data;
	Node* left;
	Node* right;
};


My Binary tree is controlled by pointer Node* root pointing to the root.
I know a simple way to print out my tree on the console screen with this function
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

void displayAll(Node* root)
{
	if(root)
	{
		cout<<root->data<<" ";
		displayAll(root->Left);	
		displayAll(root->Right);		
	}
}


But how can I print my tree in a "nicer" way, like printing each level in 1 line is something I really want to do.

Thank you for your help
1
2
3
4
5
6
7
8
9
10
11
12
Node::print(unsigned indent, ostream &os)
{
	for (unsigned i=0; i<indent; ++i) os << ' ';
	os << data << '\n';
	if (root->Left) root->Left->print(indent+1, os);
	if (root->Right) root->Right->print(indent+1, os);
}
void displayAll(Node *root)
{
	if (root) root->print(0, cout);
}

You could do this with os.width() also but I generally avoid it because you really need to restore the value if you change it.
There are a few ways you can do it. The way that would probably be the best for learning would be to implement a breadth first traversal:
https://www.cs.bu.edu/teaching/c/tree/breadth-first/

I will post an example at the end of this post.

Another way is to continue with the depth first traversal, but use system calls to move the cursor where you need it. I'm not sure which OS you use, but this seems to work for windows:
http://www.cplusplus.com/forum/general/51271/

Another way is to output more data about your Node, something like this:
1
2
3
4
5
6
if ( root )
{
  cout << root << " " << root->Left << " " << root->Right << " " << root->data << '\n';
  displayAll( root->Left );
  displayAll( root->Right );
}

That will give you enough info to be able to draw the tree in some way, so you can see if it all makes sense.

Breadth first is probably the best option though, it is a good thing to know how to do if you are learning about trees. Basically, you create another class/struct. Within that object you store a pointer to a Node, as well as the depth of that node. You then create a priority queue which will hold those objects. You do a depth first traversal, but you pass the p-queue along, inserting objects as needed. In the end, the p-queue contains the nodes in a breadth first fashion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// tree.h
#ifndef TREE_H
#define TREE_H

#include <iostream>
#include <iomanip>
#include <queue>

template <typename T>
class Tree
{
  private:
  struct Node
  {
    T data;
    Node* left;
    Node* right;

    Node( const T& data, Node* left = nullptr, Node* right = nullptr )
      :data(data), left(left), right(right)
    {
    }
  };

  Node *root;

  struct BreadthNode
  {
    const Node* node;
    int depth;

    BreadthNode( const Node* node, const int depth ): node(node), depth( depth ){}

    bool operator>( const BreadthNode& other ) const
    {
      return depth > other.depth;
    }
  };

  typedef std::priority_queue< BreadthNode, std::vector< BreadthNode>, std::greater<BreadthNode> > breadth_queue;

  public:
  Tree( void ) : root( nullptr ) {}

  virtual ~Tree( void )
  {
    destroy( root );
  }

  private:
  void destroy( Node* current )
  {
    if ( !current ) return;

    destroy( current->left );
    destroy( current->right );

    delete current;
  }

  public:
  void insert( const T& value )
  {
    root = insert( root, value );
  }

  protected:
  virtual Node* insert( Node* current, const T& value )
  {
    if ( !current ) return new Node( value );

    if ( current->data > value ) current->left = insert( current->left, value );
    if ( current->data < value ) current->right = insert( current->right, value );

    return current;
  }

  public:
  void print( void ) const
  {
    std::cout << "left to right print:\n";
    print( root, 0 );
    std::cout << '\n';

    std::cout << "breath first print:\n";
    breadth_queue queue;
    create_queue( root, 0, queue );

    print_queue( queue );
  }

  private:
  void print( const Node* current, const int depth ) const
  {
    if ( !current ) return;

    print( current->left, depth + 1 );

    std::cout << std::setw( 10 ) << current << " "
              << std::setw( 10 ) << current->left << " "
              << std::setw( 10 ) << current->right <<  " "
              << std::setw(  3 ) << current->data << " "
              << std::setw(  3 ) << depth << '\n';

    print( current->right, depth + 1 );
  }

  void create_queue( const Node* current, const int depth, breadth_queue& queue ) const
  {
    if ( !current ) return;

    queue.push( BreadthNode( current, depth ) );

    create_queue( current->left, depth + 1, queue );
    create_queue( current->right, depth + 1, queue );
  }

  void print_queue( breadth_queue& queue ) const
  {
    while ( !queue.empty() )
    {
      const Node* current = queue.top().node;
      std::cout << std::setw( 10 ) << current << " "
                << std::setw( 10 ) << current->left << " "
                << std::setw( 10 ) << current->right <<  " "
                << std::setw(  3 ) << current->data << " "
                << std::setw(  3 ) << queue.top().depth << '\n';
      queue.pop();
    }
  }
};

#endif 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// main.cpp
#include "tree.h"

#include <random>

int main( void )
{
  std::random_device rand;

  Tree<int> my_tree;

  for ( int i = 0; i < 10; ++i )
    my_tree.insert( rand() % 50 );

  my_tree.print();


  return 0;
}


The breadth first doesn't print exactly as you want it, but at least you have the correct order of nodes
Last edited on
Topic archived. No new replies allowed.