Introduction
I'm building an HTML5 web application that creates a visual representation of a binary search tree from a given list of numbers.
Currently, I have an algorithm which calculates the visual spacing between nodes on each row based on the maximum depth of the tree (which is a base-0 value):
offset = 50
offset *= pow(2, maxDepth - currentDepth)
From here, the position of the node is determined using this offset and the x-position of its parent.
The algorithm works well, because it's always able to accommodate for the widest-possible tree of any depth. However, this also makes the tree unnecessarily wide at times.
Examples
Tree branching to the left (too wide):
Tree branching to the left http://f.cl.ly/items/0c0t0L0L0o411h092G2w/left.png
Tree branching to both sides (left and right sides could be closer together).
Tree branching to both sides http://f.cl.ly/items/0r3X1j0w3r1D3v1V1V3b/left-right.png
Ideally, the above tree should be shaped like a pyramid, with a smaller width and with the sides straight, as depicted below:
Balanced tree (case where the algorithm works best):
Balanced tree http://f.cl.ly/items/203m2j2i3P1F2r2T3X02/balanced.png
Implementation
Properties
I'm using Backbone.js to create nodes from a Node model. Each node has the following properties:
- parent (the parent node)
- left (the left child node)
- right (the right child node)
- x (the x-position of the node in pixels)
- y (the y-position of the node in pixels)
The x and y properties above are calculated based on the direction the node branches from:
if (parent.get('left') === node) {
x = parentX - offsetX;
y = parentY + offsetY;
} else if (parent.get('right') === node) {
x = parentX + offsetX;
y = parentY + offsetY;
}
At this point, the x and y properties are the exact values used to position the nodes (each is positioned absolute within a container element).
Methods
- getDepth() (returns the base-0 depth of a node)
- getMaxDepth() (returns the depth of the last row in the tree)
- getRow(n) (returns an array of all nodes at depth-n)
Question
Therefore, my question is simple:
What is the best algorithm to minimize the aesthetic width of my binary tree?