To begin with, this question is not a dup of this one, but builds on it.
Taking the tree in that question as an example,
1
/ \\
2 3
/
This is breadth first search, so you can use a queue and recursively do this in a simple and compact way ...
# built-in data structure we can use as a queue
from collections import deque
def print_level_order(head, queue = deque()):
if head is None:
return
print head.data
[queue.append(node) for node in [head.left, head.right] if node]
if queue:
print_level_order(queue.popleft(), queue)
Here is a Python gist which prints the tree by level. The idea behind it is to use BFS and keep a level marker integer which marks the end the last node of the level. This is similar to Naresh's sentinel approach, but without the need of inserting a sentinel inside the queue, since this is accomplished by the level marker.
This algorithm has a space complexity of O(2tree_height)
# Print tree by levels - using BFS
# Time complexity of O(n)
# Space complexity: O(2^tree_height)
from collections import deque
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def print_levels_tree(root: Node):
q = deque()
q.append(root)
level, level_marker = 0, 1
while q:
if (level_marker == 0):
level, level_marker = level + 1, len(q)
print("", end = '\n')
level_marker -= 1
node = q.popleft()
if (node is None):
continue
print(node.data, " ", end = '')
q.append(node.left)
q.append(node.right)
# Some examples
tree = Node(19, Node(7, Node(3), Node(11)), Node(19))
print_levels_tree(tree)
left = Node(7, Node(3, Node(2), Node(5)), Node(11, None, Node(17, Node(13))))
tree = Node(19, left, Node(43))
print_levels_tree(tree)
left = Node(7, Node(3, Node(2), Node(5)), Node(11, None, Node(17, Node(13))))
right = Node(43, Node(23, None, Node(37, Node(29, None, Node(31)), Node(41))), Node(47, None, Node(53)) )
tree = Node(19, left, right)
print_levels_tree(tree)
Which prints something like:
19
7 43
3 11 23 47
2 5 17 37 53
If you want to use a \t
separator, it would look like:
19
7 43
3 11 23 47
2 5 17 37 53
This gist is available at https://gist.github.com/lopespm/993f0af88cf30b7f8c9e17982518b71b
I think what you expecting is to print the nodes at each level either separated by a space or a comma and the levels be separated by a new line. This is how I would code up the algorithm. We know that when we do a breadth-first search on a graph or tree and insert the nodes in a queue, all nodes in the queue coming out will be either at the same level as the one previous or a new level which is parent level + 1 and nothing else.
So when you are at a level keep printing out the node values and as soon as you find that the level of the node increases by 1, then you insert a new line before starting to print all the nodes at that level.
This is my code which does not use much memory and only the queue is needed for everything.
Assuming the tree starts from the root.
queue = [(root, 0)] # Store the node along with its level.
prev = 0
while queue:
node, level = queue.pop(0)
if level == prev:
print(node.val, end = "")
else:
print()
print(node.val, end = "")
if node.left:
queue.append((node.left, level + 1))
if node.right:
queue.append((node.right, level + 1))
prev = level
At the end all you need is the queue for all the processing.
Here my code prints the tree level by level as well as upside down
int counter=0;// to count the toatl no. of elments in the tree
void tree::print_treeupsidedown_levelbylevel(int *array)
{
int j=2;
int next=j;
int temp=0;
while(j<2*counter)
{
if(array[j]==0)
break;
while(array[j]!=-1)
{
j++;
}
for(int i=next,k=j-1 ;i<k; i++,k--)
{
temp=array[i];
array[i]=array[k];
array[k]=temp;
}
next=j+1;
j++;
}
for(int i=2*counter-1;i>=0;i--)
{
if(array[i]>0)
printf("%d ",array[i]);
if(array[i]==-1)
printf("\n");
}
}
void tree::BFS()
{
queue<node *>p;
node *leaf=root;
int array[2*counter];
for(int i=0;i<2*counter;i++)
array[i]=0;
int count=0;
node *newline=new node; //this node helps to print a tree level by level
newline->val=0;
newline->left=NULL;
newline->right=NULL;
newline->parent=NULL;
p.push(leaf);
p.push(newline);
while(!p.empty())
{
leaf=p.front();
if(leaf==newline)
{
printf("\n");
p.pop();
if(!p.empty())
p.push(newline);
array[count++]=-1;
}
else
{
cout<<leaf->val<<" ";
array[count++]=leaf->val;
if(leaf->left!=NULL)
{
p.push(leaf->left);
}
if(leaf->right!=NULL)
{
p.push(leaf->right);
}
p.pop();
}
}
delete newline;
print_treeupsidedown_levelbylevel(array);
}
Here in my code the function BFS prints the tree level by level, which also fills the data in an int array for printing the tree upside down. (note there is a bit of swapping is used while printing the tree upside down which helps to achieve our goal). If the swapping is not performed then for a tree like
8
/ \
1 12
\ /
5 9
/ \
4 7
/
6
o/p will be
6
7 4
9 5
12 1
8
but the o/p has to be
6
4 7
5 9
1 12
8
this the reason why swapping part was needed in that array.
Making use of queues(constant space complexity)
def bfs(self, queue=None):
if(queue is None):
queue = deque([self.root])
elif(not queue):
return
currNode = queue.pop()
print(currNode.data)
if currNode.left:
queue.appendleft(currNode.left)
if currNode.right:
queue.appendleft(currNode.right)
self.bfs(queue)
The following code will print each level of binary tree into new line:
public void printbylevel(node root){
int counter = 0, level = 0;
Queue<node> qu = new LinkedList<node>();
qu.add(root);
level = 1;
if(root.child1 != null)counter++;
if(root.child2 != null)counter++;
while(!qu.isEmpty()){
node temp = qu.remove();
level--;
System.out.print(temp.val);
if(level == 0 ){
System.out.println();
level = counter;
counter = 0;
}
if(temp.child1 != null){
qu.add(temp.child1);
counter++;
}
if(temp.child2 != null){
qu.add(temp.child2);
counter++;
}
}
}