0

I've been looking for a way to complete this non-recursive method for hours. Our programming teacher has asked us to complete both a recursive and a non-recursive implementation of the same method, used to display the BinaryHeap in the console (I use Eclipse).

Here's my code for my methods:

public String nonRecursivePrintFancyTree()
{
    String outputString = "";

    /**********I DON'T KNOW WHAT TO DO HERE**********/

    return outputString;
}

public String printFancyTree()
{
    return printFancyTree( 1, "");
}

private String printFancyTree(int index, String prefix)
{
    String outputString = "";

    outputString = prefix + "|__";

    if( index <= currentSize )
    {
        boolean isLeaf = index > currentSize / 2;

        outputString += array[ index ] + "\n";

        String _prefix = prefix;

        if( index%2 == 0 )
            _prefix += "|  "; // one | and two spaces
        else
            _prefix += "   " ; // three spaces

        if( !isLeaf )
        {
            outputString += printFancyTree( 2*index, _prefix);
            outputString += printFancyTree( 2*index + 1, _prefix);
        }
    }
    else
        outputString += "null\n";

    return outputString;
    }
}

Completing the recursive method took me some time, but I can't figure out an easy way to complete the non-recursive method.

This is my main class, used to check if the methods work as they should:

public class Main 
{
/**
 * Main function of the class
 */
public static void main(String[] args) 
{
    // create a Heap with 22 elements and an equivalent array
    int numItems = 22;
    BinaryHeap<Integer> heap = new BinaryHeap<Integer>();
    Integer [] items = new Integer[numItems];

    int i;
    int j;

    // elements are inserted one by one
    for (i = 11, j = 0; j != numItems; i = (i + 37), j++)
    {
        heap.insert(i);
        items[j] = i;
        i %= numItems; 
    }

    heap.buildMaxHeap();
    System.out.println("Recursive display:");
    System.out.println(heap.printFancyTree());

    System.out.println("Non recursive display:");
    System.out.println(heap.nonRecursivePrintFancyTree());  //<------this method


}

Here's what the display should look like:

|__58
   |__56
   |  |__53
   |  |  |__50
   |  |  |  |__11
   |  |  |  |__39
   |  |  |__48
   |  |     |__46
   |  |     |__43
   |  |__54
   |     |__47
   |     |  |__40
   |     |  |__38
   |     |__51
   |        |__49
   |        |__null
   |__57
      |__44
      |  |__41
      |  |__42
      |__52
         |__37
         |__45

Basically, it should give me the same display for both the recursive and non-recursive methods. I've looked everywhere: on Google, this very website, on Oracle documentation, even my course's Manual (Data structures and Algorithm Analysis in JAVA, 3rd ed., Mark Allen Weiss) and i can't even find a single possible way to do this. My question is, what is a possible implementation of "nonRecursivePrintFancyTree" ? Thanks in advance.

Zachariel
  • 96
  • 1
  • 13
  • 2
    The keyword you need to search is [preorder tree traversal](http://www.algorithmsandme.com/2015/03/preorder-traversal-of-tree-without.html?m=1#.VP3OQNKUfA0). – Lie Ryan Mar 31 '15 at 04:35
  • Here you can read some examples of [general way to convert recursive function to an iterative one](http://stackoverflow.com/questions/26682075/how-do-you-best-convert-a-recursive-function-to-an-iterative-one) – nem035 Mar 31 '15 at 04:36
  • @LieRyan It can be even simpler, since relation between position in the storage array and position in tree for binary heap is pretty simple. Implementing stack by hand is pretty much the same as recursion IMO, but maybe that is what is expected. – luk32 Mar 31 '15 at 04:37
  • the use of recursion for this method is strictly forbidden. @luk32 Wouldn't implementing stack by hand be the easiest, but also cheapest, way to do it? (Without calling a private method) – Zachariel Mar 31 '15 at 04:45
  • 1
    A stack isn't needed since in a heap you can easily get both children and parent nodes. You can write a in-place iterative algorithm. – Zong Mar 31 '15 at 04:48
  • @Zachariel Stack is emulation of recursion performed by compiler, that's why I have doubts if it would count. You don't convert the algorithm at all, just tweak implementation a bit not to use language internals. But maybe points for creativity would make it slip. As I said, the relations between position in tree, parents and children are simple for a binary heap. So it's not needed. – luk32 Mar 31 '15 at 04:53
  • Thanks for the tips guys! Very helpful! Now I will do my best to find a valid implementation. :) – Zachariel Mar 31 '15 at 05:02

1 Answers1

0

Try this:

public static void print(int[] minHeap, int minWidth) {

    int size = minHeap.length;

    int level = log2(size);
    int maxLength = (int) Math.pow(2, level) * minWidth;
    int currentLevel = -1 ;
    int width = maxLength;

    for (int i = 0; i < size; i++) {
        if (log2(i + 1) > currentLevel) {
            currentLevel++;
            System.out.println();
            width = maxLength / (int) Math.pow(2, currentLevel);
        }
        System.out.print(StringUtils.center(String.valueOf(minHeap[i]), width));
    }
    System.out.println();
}

private static int log2(int n) {
    return (int) (Math.log(n) / Math.log(2));
}

The idea of this code snippet is dividing the maxLength which is the total bytes of bottom line by the number of elements of each line to get the block width. Then put the element in the middle of each block.

The parameter minWidth implys the length of blocks in the bottom line.

A picture to illustrate the idea and show the result.

VWagen
  • 1
  • 1