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

Print binary search tree by levels function implementation

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

Problem

I do not like this implementation as is seems too much complicated. My idea was to implement some BFS algorithm variant.

Some points to notice:

  • I use one queue.



  • In the begining put the tree root in the queue and dummy treeNode delimiter which is recognized by its data == -1.



(I need this for distiguishing between tree levels).

  • After each level I assign -1 to the queue.



Any suggestions of how to simplify it? (Currently seem to work good)

public void printTreeByLevels() // Should be BFS variant implementation
{
    int levelCounter = 0;
    boolean currNodeHasChild = false;
    Queue q = new ArrayDeque();

    q.add(m_Root);
    q.add(new TreeNode(-1));
    System.out.print("Level:" + levelCounter+ " ");

    while (!q.isEmpty())
    {
        TreeNode currentNode = q.poll();
        currNodeHasChild = false;
        if(currentNode.m_Data == -1)
        {
            TreeNode nextQueueNode = q.peek();
            while(nextQueueNode!= null && currentNode.m_Data == -1)
            {
                currentNode = q.poll(); //bypassing delimiters        
            }                        

            if(currentNode.m_Data != -1)
            {
                levelCounter++;
                System.out.println();
                System.out.print("Level:" + levelCounter+" ");
            }
            else if(nextQueueNode == null)
            {
                break;
            }

        }            

        System.out.print("\t"+currentNode.m_Data);

        if(currentNode.m_LeftNode!= null)
        {
            q.add(currentNode.m_LeftNode);    
            currNodeHasChild = true;
        }

        if(currentNode.m_RightNode!=null)
        {
            q.add(currentNode.m_RightNode);
            currNodeHasChild = true;
        }            

        if(currNodeHasChild)
        {
            q.add(new TreeNode(-1)); // sign of next level
        }                        
    }
}

Solution

General Notes

Let me preface this section with the fact that I have not looked at Java conventions in a while. Some of these suggestions may stray from classic Java conventions.

With that off my chest, visually your code looks pretty good, though mixture of underscores in your hungarian notation is a little bit odd (Thanks Vogel612).

// Could you not just have 'currentNode.mRightNode'?
if(currentNode.m_RightNode!=null)


You also have several loops or if-statements with only a single line of code in them. This may just be preference, but if you remove the braces in those cases:

if(currNodeHasChild)
{
    q.add(new TreeNode(-1)); // sign of next level
}


becomes

if(currNodeHasChild)
    q.add(new TreeNode(-1)); // sign of next level


which makes the code more compact without reducing readability.

NOTE: When using no-brace notation, only ONE LINE after the if-statement, for-loop, etc. will be considered 'inside' that block of code. As Vogel612 pointed out in a comment below, there have been cases where this notation was misused. Keep an eye out for these bugs, as they can pop up relatively easily.

One final thing: I do not prefer in-line comments. To my eyes, they break up the flow of the program visually.

BFS Solution

Now onto code improvements.

This problem is built to be solved by recursion. Combining recursion and a breadth-first search yields a relatively simple solution:

public void printTreeByLevels(Queue nodes, int level)
{
    System.out.println("Level " + level);

    // New queue to hold child nodes
    Queue newNodes = new ArrayDeque();

    // Loop through all nodes in the queue
    for(TreeNode node : nodes)
    {
        System.out.println("\t" + node.m_Data);

        // Add child nodes if they exist      
        if(node.m_LeftNode != null)
            newNodes.add(node.m_LeftNode);
        if(node.m_RightNode != null)
            newNodes.add(node.m_RightNode);
    }

    // Call this function again only if one or many child node(s) were found
    if(!newNodes.isEmpty())
        printTreeByLevels(newNodes, level+1);
}


A single for-loop and some if-statements solve this problem quite simply and easily.

NOTE: I originally wrote this in Python as its been a while since I wrote Java. However, the syntax should all be correct.

Code Snippets

// Could you not just have 'currentNode.mRightNode'?
if(currentNode.m_RightNode!=null)
if(currNodeHasChild)
{
    q.add(new TreeNode(-1)); // sign of next level
}
if(currNodeHasChild)
    q.add(new TreeNode(-1)); // sign of next level
public void printTreeByLevels(Queue<TreeNode> nodes, int level)
{
    System.out.println("Level " + level);

    // New queue to hold child nodes
    Queue<TreeNode> newNodes = new ArrayDeque<TreeNode>();

    // Loop through all nodes in the queue
    for(TreeNode node : nodes)
    {
        System.out.println("\t" + node.m_Data);

        // Add child nodes if they exist      
        if(node.m_LeftNode != null)
            newNodes.add(node.m_LeftNode);
        if(node.m_RightNode != null)
            newNodes.add(node.m_RightNode);
    }

    // Call this function again only if one or many child node(s) were found
    if(!newNodes.isEmpty())
        printTreeByLevels(newNodes, level+1);
}

Context

StackExchange Code Review Q#49546, answer score: 2

Revisions (0)

No revisions yet.