faqts : Computers : Programming : Algorithms : Datastructure : Graph : Tree : Binary tree

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

1 of 1 people (100%) answered Yes
Recently 1 of 1 people (100%) answered Yes

Entry

Datastructure: Tree: Binary: Print: Upright: How to print a binary tree upright? Rotate right

Feb 5th, 2005 12:12
Knud van Eeden,


----------------------------------------------------------------------
--- Knud van Eeden --- 23 October 2003 - 11:31 pm --------------------

Datastructure: Tree: Binary: Print: Upright: How to print a binary 
tree upright? Rotate right

---

Method: Rotate over 90 degrees: Worked out:

So one method would be to print the tree sideways
(which is just a vertical tree rotated 90 degrees
to the left), and when you are finished, you
rotate it 90 degree to the right (so that it is
upright).

---

So the key to easy upright printing is to make 2 passes.

1. The first pass determines the x, y position of the node

   1. you store this x,y position e.g. in an array

        x    y   value

2. The second pass reads the x, y coordinates and value from the array
   and puts this in the correct 90 degrees anticlockwise rotated
   position

---
---

Steps:


1. the easy sideways 'horizontal tree'

2. Use the 2D rotation transformation for anticlockwise rotation:

    In  general:

    xnew = cos( rotationangle ) . xold + sin( rotationangle ) . yold

    ynew = - sin( rotationangle ) . xold + cos ( rotationangle ) . yold

3. In the special case that the rotationangle is ninety degrees,
    you have in that case that

     rotationangle = 90 degrees

    thus cos( 90 degrees ) = 0

            sin( 90 degrees ) = 1

4. Fill in step 3. in step 2, that gives:

      xnew = 0 . xold + 1 . yold

      ynew = -1. xold + 0 . yold

5. So step 4. simplifies to:

       xnew = yold

       ynew = -xold

6. Thus to rotate the 'easy' tree upwards over 90 degrees,for each of 
your

     ( xold, yold )  coordinates in that rectangle around the old tree,

     you write it instead as ( yold, -xold ), and print that instead on
     the screen.

7. Now working this idea out:

8. So that means that you could draw a rectangle around your old 'easy'
   tree

                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  in this area your |  |
                      +--+--+--+--+--+--+--+--+
                      |  |easy tree is drawn  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+

9. You divide this rectangle in smaller rectangles with height 1 and
   breadth 1.


                     xminI,yminI
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                                          xmaxI,ymaxI

10. Here an example of the binary tree for '3 + 4 * 5' sideways printed

    1. the binary tree '3 + 4 * 5' put sideways in this rectangle:

                     xminI,yminI
                      +--+--+--+--+--+--+--+--+
                      |  |5 |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |* |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |4 |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |+ |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                      |  |  |3 |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                                          xmaxI,ymaxI



     2. And here with the coordinates on the sides

                       1  2  3  4  5  6  7  8 -> x
                      +--+--+--+--+--+--+--+--+
                    1 |  |5 |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                    2 |* |  |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                    3 |  |  |4 |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                    4 |  |+ |  |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                    5 |  |  |3 |  |  |  |  |  |
                      +--+--+--+--+--+--+--+--+
                    |
                    v

                    y



     3. Thus you could represent this rectangle with its
        content by an array

           xold    yold  value

          ---------------------

           2       1     "5"

           1       2     "*"

           3       3     "4"

           2       4     "+"

           3       5     "3"


11. And then for each of this values, you rotate it to the right over
    90 degrees:

For each of th values
 take its x,y coordinate
 show y, -x coordinate instead to rotate
Endfor

11. Thus this would become something like:

  FOR xI = xminI TO maxI

     Get information at xI, yI

     Show instead at yI, -xI

 ENDFOR

---

12. Thus the example list would become
    (replace its x value by its old y value, and
     replace its y value by its old -x value)

     ---

           xnew    ynew  value

          ---------------------

           1      -2     "5"

           2      -1     "*"

           3      -3     "4"

           4      -2     "+"

           5      -3     "3"

      ---

13. Now you see there is a little complication,
    as the y values are negative.

    This is because in a usual grid the
    positive y-values go upwards.
    So negative means they have to
    go downwards.

    But in our grid positive y-values
    go DOWNwards.

    So negative y values in a usual grid mean
    positive y values in our grid.

    Now you can easy fix this, by multiplying each y-value by -1 (this
    is actually the rotate vertically over 180 degrees transformation,
    that is xnew = xold, and ynew = -yold).

    So after multiplying each y-value by -1,
    the array becomes now:


           xnew    ynew  value

          ---------------------

           1       2     "5"

           2       1     "*"

           3       3     "4"

           4       2     "+"

           5       3     "3"


14. So to do this all at once, we should so
    have used

       xnew = yold

       ynew = -1 . ( -xold )

    or thus

       xnew = yold

       ynew = xold

15. Representing the array with its values
    and new x,y coordinates again in the rectangle, using
    this new x,y coordinates gives:

              1  2  3  4  5  6  7  8 -> x
             +--+--+--+--+--+--+--+--+
           1 |  |* |  |  |  |  |  |  |
             +--+--+--+--+--+--+--+--+
           2 |5 |  |  |+ |  |  |  |  |
             +--+--+--+--+--+--+--+--+
           3 |  |  |4 |  |3 |  |  |  |
             +--+--+--+--+--+--+--+--+
           4 |  |  |  |  |  |  |  |  |
             +--+--+--+--+--+--+--+--+
           5 |  |  |  |  |  |  |  |  |
             +--+--+--+--+--+--+--+--+
           |
           v

           y


16. In other words the sideways tree has been rotated over
    90 degrees to the left, and so this tree is now
    shown upright

17. Sorting: But again there shows a little complication.

    You want to print the tree in one pass, so going through the array
    from the first to the last entry, and print the value on the
    correct y-position.

    That means the the lowest y-value should be taken first, the but
    lowest y-value next, and so on, until you reach the last y-value
    which should have the largest value

   (This because your 'print head' can not go back upwards, but only
    downwards, in this simplest possible case of controlling a 'print
    head'. Of course there are languages where you could use 'PRINT
    TAB( X, Y )' or 'GOTOXY' on the screen but here for the moment only
    'PRINT' or WRITELINE statements are used).

    That means the y-values should be ordered on the y value.

    So you should sort the vertical y-values in the array first (so
    that the smallest y comes first and the largest y comes last):

    ---

    1. This sorting gives as a result:


           xnew    ynew  value

          ---------------------

           2       1     "*"

           1       2     "5"

           4       2     "+"

           3       3     "4"

           5       3     "3"

    ---

    And after I tried this algorithm, it shows that also
    you have to sort on the x column, which complicates
    the matter further, because otherwise your printhead
    might have to return back on the same line if you
    printed a larger x-value first, and then have to return
    on the same line to a smaller x-value. If you use e.g.
    'PRINT' only this is usual not possible, the only result
    of a new PRINT value will be that the 'printhead' will
    go to the next line. So the x-values should be sorted
    from small to large, so that the printhead does not
    have to return.

    2. To sub sort all given x-values for a given constant y-value,

    you could solve this by going through the values
    of the y column, then noting the equal values.

    You note the first and last equal y value range.

    Thus e.g. in the example in line two the y-value is 2,
    and in line 3 the y-value is also 3.

    You call then your sort routine again, which has
    usually a parameter for the beginning position in the
    array and the ending position in the array, thus the
    range which it has to sort, with this found equal
    begin y-value and equal end y-value.
    And you sort on the x-array

    ---

    3. So you find first that on line one only one
    y-value with the equal value 1.

    So you call your sort routine with this
    range y-value range:

     e.g. PROCQuickSortMain( firstI%, lastI% )
     becomes here
     PROCQuickSortMain( 1, 1 )

     So you get after 'sorting' the first line

          xnew    ynew  value

          ---------------------

           2       1     "*"

           1       2     "5"

           4       2     "+"

           3       3     "4"

           5       3     "3"

    3. So you find first that on line two and three
    y-values with the equal value 2

    So you call your sort routine with this
    range y-value range:

     e.g. PROCQuickSortMain( firstI%, lastI% )
     becomes here
     PROCQuickSortMain( 2, 3 )

     So you get after 'sorting' the second and third line

          xnew    ynew  value

          ---------------------

           2       1     "*"

           1       2     "5"

           4       2     "+"

           3       3     "4"

           5       3     "3"

    4. So you find first that on line four and five
    y-values with the equal value 3

    So you call your sort routine with this
    range y-value range:

     e.g. PROCQuickSortMain( firstI%, lastI% )
     becomes here
     PROCQuickSortMain( 4, 5 )

     4. So you get after 'sorting' the fourth and fifth line:

          xnew    ynew  value

          ---------------------

           2       1     "*"

           1       2     "5"

           4       2     "+"

           3       3     "4"

           5       3     "3"


    ---

     Actually, by incident this particular example was already
     sorted, so there is no change. But the idea should be
     clear. You have to sort on y and then to subsort on x.

    ---

18. So if you ask for NO random positioning of the 'printhead',
    and so you print fluently by going from top to bottom,
    and from left to right, with no returns, you get this
    algorithm:

    1. First pass to get the old x,y coordinates

       1. print the tree sideways

          1. store its x coordinate in an array

          2. store its y coordinate in an array

          3. store its value in an array

    2. Second pass to print it on position new
       x,y coordinates

       1. for first to last value in the array

          1. get its x coordinate, by taking its old y coordinate

          2. get its y coordinate, by taking its old x coordinate

       2. sort this array

          1. sort on the y-column

          2. sort on the x-column

       3. for first to last value in the array

          1. print the value:

             1. first horizontally an amount of spaces proportional to
                the x coordinate

             2. then you print the value on that horizontal position

---
---

18. So if you can use random positioning e.g. using GotoXY() or
    similar, your routine becomes much easier.

    1. First pass to get the old x,y coordinates

       1. print the tree sideways

          1. store its xnew coordinate in an array

          2. store its ynew coordinate in an array

          3. store its value in an array


    2. Second pass to print it on position new
       x,y coordinates

       1. for first to last value in the array

          1. print the value:

             1. Goto the position x,y

             2. print the value on that position x,y

---
---

Internet: see also:

---

Datastructure: Link: Overview: Can you give an overview of links?
http://www.faqts.com/knowledge_base/view.phtml/aid/32054/fid/1264

----------------------------------------------------------------------