Ambiguity with the Top View of a binary tree - data-structures

What exactly is the top view of a binary tree?
I find great ambiguity and lack of clarity from the articles I find.
For example, this is what is used to demonstrate the top view on geeksforgeeks:
1
/ \
2 3
/ \ / \
4 5 6 7
They go on to say that the top view is 4 2 1 3 7. The problem here is that they leave a lot of speculation on what isn't the top view. Consequently it becomes ambiguous to implement in code.
Stackoverflow examples so far are not any better. Hackerrank's example is even worse.
So I am hoping someone will tell me explicitly what the top view is because I have been trying to find out for 2 days. For instance, what is the top view of this tree:
1
\
14
/ \
3 15
/ \
2 7
/ \
4 13
/ \ /
5 6 10
/ \
8 11
\ \
9 12
And if I may be bold to ask, why is it important?

Now to understand the definition of top view,the best way is to know how to find the top view of a tree.
Finding the top view is a combination of two traversals namely-> Level Order Traversal and Vertical Traversal(There are other ways too but this one is the most basic).
To visualise this,start drawing vertical lines in the tree,in your second example 6 vertical lines would be drawn covering nodes, 1st -> 2,5 || 2nd -> 1,3,4 || 3rd -> 14,7,6,8 || 4th -> 15,13,10,9 || 5th -> 11 || 6th -> 12.
Now traverse the leaders of these vertical lines and this will give the top view of the tree 2->1->14->15->11->12.
Its like your're keeping your eye on the top of the tree and start drawing straight lines,the nodes which the straight lines cut first before touching any other nodes is the top view of the tree.
Like all other questions on hackerrank which helps in strengthening your base concept ,finding top view helps you understand the level order traversal and the vertical traversal concepts in detail.

To answer your question i will ask you to assume a rough sketch to actually understand what the question top view asks for. You might assume you are watching this tree with the root of the binary tree as the peak of a tree from a helicopter from above.
Assume the rank of the root to be 0. You need to traverse the tree in level order. If you go towards left decrease the current rank by 1 and when going right increase the current rank by 1. You will then be able to see that only unique values of every rank comes out as output.
The rank is actually the horizontal distance from the root node.
Like in the first example :
------- 1 (0) -------
/ \
2 (0-1=-1) 3 (0+1=1)
/ \ / \
4 (-1-1=-2) 5 (-1+1=0) 6 (1-1=0) 7 (1+1=2)
In brackets i have written down the ranks to which i was referring to.
So the final output if asked to write from left to right as asked in GeeksForGeeks, you can print the corresponding numbers of each unique ranks sorted according to the ranks.
And i guess it is clear now as to why 5 (rank=0) and 6(rank=0) are not in the final answer. Since when seen from the top of a tree these numbers will be shadowed by 1(rank=0).
map<int,int> mp;
void topView(Node * root) {
if(!root)
return;
mp.insert({0,root->data});
queue<pair<Node*,int>> q;
q.push({root,0});
while(!q.empty()){
Node *tmp=q.front().first;
int dis=q.front().second;
q.pop();
if(tmp->left){
q.push({tmp->left,dis-1});
if(mp.find(dis-1)==mp.end()){
mp.insert({dis-1,tmp->left->data});
}
}
if(tmp->right){
q.push({tmp->right,dis+1});
if(mp.find(dis+1)==mp.end()){
mp.insert({dis+1,tmp->right->data});
}
}
}
for(auto i : mp){
cout<<i.second<<" ";
}
}
The accepted solution to the above problem.
Link : Well explained! Refer for step by step explanation. https://stackoverflow.com/a/31388101/13962659

I don't know of a technical or mathematical definition for you, but it would appear from the links that the top view of the tree is as follows:
Imagine your tree laid out on the surface of a table. Look from the root end of the table down along the length of it. Supposing that the values of nodes are written on small wooden blocks, and the links between them are represented by wooden blocks high enough to obscure any nodes behind them, which nodes can you see when you lower your head to table height? In the first example, 5 and 6 are obscure, whereas 2, 3, 4 and 7 extend outwards to the left or right such that they are still visible.
However, as your second example illustrates, this is ambiguous as to whether or not the nodes 2, 5, 11, 12, 13 extend far enough outwards to be visible.
It seems like a poorly defined concept, which probably means it's not worth worrying about.

I noticed that nobody explains why you need to use level order traversal exactly and not simply any other kind of recursive traversals.
And here's the reason: a binary tree might have skewed left subtree by overlapping the right one beneath it or vice versa, take a look at the examples below.
A B
1 5
/ \ / \
4 2 4 7
\ \ / /
6 5 9 11
\ /
3 13
\ /
11 7
\ /
2 3
So if you traverse left nodes first you will have wrongly written right first w:node values in test case A and if you start traversing right nodes first then testcase B fails
Only traversing level by level guarantees that you store a correct top view values.

It works well and easy solution
import java.util.*;
import java.io.*;
class Node {
Node left;
Node right;
int data;
Node(int data) {
this.data = data;
left = null;
right = null;
}
}
class Solution {
/*
class Node
int data;
Node left;
Node right;
*/
class Nodegen
{
Node node;
int gen;
public Nodegen(Node node,int gen)
{
this.node=node;
this.gen=gen;
}
}
public static void topView(Node root) {
Map<Integer,Nodegen> topview=new TreeMap<>();
new Solution().printView(root,0,0,topview);
// System.out.print(topview.size());
for (Map.Entry<Integer, Nodegen> entry : topview.entrySet()) {
System.out.print(entry.getValue().node.data+" ");
}
}
public void printView(Node root,int align,int gen,Map<Integer,Nodegen> map) {
if(root==null)
{
return ;
}
if(map.get(align)==null)
{
map.put(align,new Nodegen(root,gen));
}else{
if(map.get(align).gen>gen)
{
map.put(align, new Nodegen(root,gen));
}
}
int temp=align+1;
int temp1=align-1;
int temp2=gen+1;
printView(root.left,temp1,temp2,map);
printView(root.right,temp,temp2,map);
}
public static Node insert(Node root, int data) {
if(root == null) {
return new Node(data);
} else {
Node cur;
if(data <= root.data) {
cur = insert(root.left, data);
root.left = cur;
} else {
cur = insert(root.right, data);
root.right = cur;
}
return root;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
Node root = null;
while(t-- > 0) {
int data = scan.nextInt();
root = insert(root, data);
}
scan.close();
topView(root);
}
}

Related

Algorithm to construct Fibonacci's tree with given minimum

I want to make a Fibonacci tree but with a minimum number other than 1, and I can't seem to find anything about it.
Here's an example of a "normal" fibonacci tree, with the minimum node 1.
5
/ \
3 7
/ \ /
2 4 6
/
1
What I want to do is for example, with minimum 3:
With height 0: it would be the empty tree.
With height 1:
3
With height 2:
4
/
3
With height 3:
5
/ \
4 6
/
3
With height 4:
7
/ \
5 9
/ \ /
4 6 8
/
3
...And so on.
My problem is, I can't seem to see a pattern in it, so I can't think of an algorithm to write.
I know that the left subtree's height is h-1 (where h is the original given height) and the right subtree's height is h-2. And I can't see how they calculate the root's number. But other than that, I'm really stuck.
Since the Fibonacci tree is a recursively defined structure, the easiest way is to think about a recursive algorithm.
This is some sort of C-style pseudo code (not covering any edge cases - I leave that to you as part of the exercise).
function createTree(height)
{
// basic cases
if(height == 0) return NULL;
if(height == 1)
{
node = new Node;
node.numNodesInTree = 1;
}
else
{
// according to the definition of the fibonacci tree
node = new Node;
node.leftChild = createTree(height - 1);
node.rightChild = createTree(height - 2);
node.numNodesInTree = node.leftChild.numNodesInTree
+ node.rightChild.numNodesInTree
+ 1; // also count the current node
}
return node;
}
You end up with a tree that has the Fibonacci structure, but not the right numbers yet. As a little helper, you have the number of nodes for each sub tree.
Then you can do something like:
function fillTree(offset, node, minimum) // offset means "all numbers in this subtree must be bigger than offset"
{
// According to the binary search tree definition,
// all numbers in the left sub tree have to be lower than
// the current node.
// All nodes in the right sub tree have to be larger.
node.value = node.leftChild.numNodesInTree // the number has to be bigger than all numbers in the left sub tree
+ 1 // (that's the "one bigger")
+ offset // offset for right subtrees
+ minimum - 1; // Just stupidly add the minimum (as mentioned in the comment to your question)
fillTree(offset, node.leftChild, minimum); // propagate offset to left children
fillTree(node.value, node.rightChild, minimum); // for the right sub tree, the current node's value is the new offset
// because all nodes in the right sub tree have to be bigger than the current node (binary search criterion)
}
Then you can call it like:
root = createTree(height);
fillTree(0, root, 3); // when initially calling it, the offset is always 0
// You can set the minimum arbitrarily (i.e. 3 as in your example)
Since this is pseudo code, I obviously haven't tested it, but you could get the idea behind that.

View of a binary tree from 45 degree

So I am not asking diagonal view of a tree, which fortunately I already know. I am asking if I view a tree from 45-degree angle only a few nodes should be visible. So there is a plane which at an angle of 45-degrees from the x-axis. so we need to print all the nodes which are visible from that plane.
For example:
1
/ \
2 3
/ \ / \
4 5 6 7
So if I look from that plane, I will only see nodes [4, 6, 7] as 5 and 6 overlaps each other. If I add another node at 6, now it will hide 7. How to do that? I searched on internet but couldn't find the answer.
Thanks!
I am giving you an abstract answer as the question is not language specific.
The problem with logging trees like this is the use of recursion.
By that I mean the traversal is going down nodes and up nodes.
What if you wrote a height helper which would return the depth of the current node.
For each depth level, you place the value in an array.
Then, write the values of the array.
Then you could grab the length of the last array and determine the amount of spaces each node needs.
Allow the arrays to hold empty values or else you will have to keep track of which nodes dont have children.
int total_depth = tree.getTotalHeight();
int arr[total_depth] = {};
for(int i = total_depth; i--;){
// there is a formula for the max number of nodes at a given depth of a binary tree
arr[i] = int arr[maximum_nodes_at_depth]
}
tree.inorderTraverse(function(node){
int depth = node.getHeightHelper();
// check if item is null
if( node!=nullptr && node.Item != NULL)
{
arr[depth].push(node.Item)
}
else
{
arr[depth].push(NULL)
}
})
So now you would have to calculate the size of your tree and then dynamically calculate how many spaces should prefix each node. The lower the depth the more prefixed spaces to center it.
I apologize but the pseudocode is a mix of javascript and c++ syntax.... which should never happen lol

Explain black height algorithm in Red-Black tree

I have looked around for a way to check this property of a red black tree: "Every path from a node to a null node must contain the same number of black nodes".
Most of the upvoted answers look like this:
// Return the black-height of node x. If its subtrees do not have
// the same black-height, call attention to it.
private int checkBlackHeight(Node x) {
if (x == null)
return 0;
else {
int leftBlackHeight = checkBlackHeight(x.left) +
(x.left.isBlack() ? 1 : 0);
int rightBlackHeight = checkBlackHeight(x.right) +
(x.right.isBlack() ? 1 : 0);
if (leftBlackHeight != rightBlackHeight)
complain("blackheight error", x);
return leftBlackHeight;
}
}
What I am confused about is, doesn't this code only check for the leftmost and rightmost paths down the tree? How does it check for the inner paths?
e.g. In the tree below, it should check the path 11-9-8-.. and 11-16-18... but does it check 11-16-13- (some inner nodes) -...
11
/ \
9 16
/ \ / \
8 10 13 18
/\ /\ /\ / \
Thank you in advance!
The reason the code ends up checking all the paths, the way I understand it at least, is because the function has both a "go left" and "go right" instruction, so for each node both left and right are explored, and so all the paths will be covered. Additionally, determining whether the left node is black simply determines whether to add one to the black path length (for each recursive call).

Binary Tree Transformation

1 5
/ \ |
2 3 --> 2
/ \ / \ / \
4 5 6 7 1 4
|
3
/ \
6 7
Let say you have a binary tree like the one on the left and try to convert it to the one on the right.
What it does is that it bumps 'any' single leaf node of the binary tree -- this case '5' -- which makes the leaf node a new root node. The original root node (and it's children) -- this case '1' and its children -- takes up the then leaf node space.
What's would be the general algorithm for this?
Thank you for help.
That depends pretty much on the structure supporting the binary tree (for example, if you store the parent of each node or not, and so on). Supposing you store the value of the node and the left and right descendants (the most basic information), the problem is reduced to "reverse" all the arcs from the current root down to the node that will become the new root. Something like this, I guess, in Java-style pseudo-code:
void rev(Node u, Node v) {
// make v point back to u
if (v.left == null) v.left = u;
else v.right = u;
// free edge from u to link up
if (u.left == v) u.left = null;
else u.right = null;
}
boolean reroot(Node root, Node parent, Node newRoot) { // assumes that newRoot is a leaf
if (root != null)
if (root == newRoot) {
rev(root, parent);
return true;
} else {
if (reroot(root.left, root) || reroot(root.right, root)) {
rev(root, parent);
return true;
}
}
}
return false;
}
Nevertheless, I didn't test the code above.
EDIT: the initial call would be reroot(currentRoot, null, newRoot);
My thoughts: starting from a node, we add its parent node and another unexplored branch to the new tree as the new branches, and then we recursively build the new tree by iterating back through the original tree till its root.
a python style pseudo-code would be like this:
NewTree=Node
NoLongerChildNode=NULL
while (Node!=root):
NewTree.attach(Node.anotherchild(NoLongerChildNode))
NewTree=NewTree.attach(Node.parent)
NoLongerChildNode=Node
Node=Node.parent
NewTree.attach(Node.anotherchild(NoLongerChildNode))

Algorithm to Render a Horizontal Binary-ish Tree in Text/ASCII form

It's a pretty normal binary tree, except for the fact that one of the nodes may be empty.
I'd like to find a way to output it in a horizontal way (that is, the root node is on the left and expands to the right).
I've had some experience expanding trees vertically (root node at the top, expanding downwards), but I'm not sure where to start, in this case.
Preferably, it would follow these couple of rules:
If a node has only one child, it can be skipped as redundant (an "end node", with no children, is always displayed)
All nodes of the same depth must be aligned vertically; all nodes must be to the right of all less-deep nodes and to the left of all deeper nodes.
Nodes have a string representation which includes their depth.
Each "end node" has its own unique line; that is, the number of lines is the number of end nodes in the tree, and when an end node is on a line, there may be nothing else on that line after that end node.
As a consequence of the last rule, the root node might be better off in either the top left or the bottom left corner; top left is preferred.
For example, this is a valid tree, with six end nodes (node is represented by a name, and its depth): EDIT: Please see bottom of question for an alternative, easier rendering
[a0]-----------[b3]------[c5]------[d8]
\ \ \----------[e9]
\ \----[f5]
\-[g1]--------[h4]------[i6]
\ \--------------------[j10]
\-[k3]
Which represents the vertical, explicit binary tree:
0 a
/ \
1 g *
/ \ \
2 * * *
/ \ \
3 k * b
/ / \
4 h * *
/ \ \ \
5 * * f c
/ \ / \
6 * i * *
/ / \
7 * * *
/ / \
8 * * d
/ /
9 * e
/
10 j
(branches folded for compactness; * representing redundant, one-child nodes; note that *'s are actual nodes, storing one child each, just with names omitted here for presentation sake)
(also, to clarify, I'd like to generate the first, horizontal tree; not this vertical tree)
I say language-agnostic because I'm just looking for an algorithm; I say ruby because I'm eventually going to have to implement it in ruby anyway.
Assume that each Node data structure stores only its id, a left node, and a right node.
A master Tree class keeps tracks of all nodes and has adequate algorithms to find:
A node's nth ancestor
A node's nth descendant
All end-node descendants of a node, and their count
The generation of a node
The lowest common ancestor of two given nodes
I already know:
The number of end nodes
Anyone have any ideas of where I could start? Should I go for the recursive approach? Iterative?
Some Psuedo-code would be pretty cool too, and much appreciated =)
progress
As per walkytalky's suggestion, I decided to see what it would look like to map each "relevant" or significant node to a grid, with the columns being the depth and the rows identifiable by their end nodes. Here is what happens (skipping column 7 because there are no significant nodes in depth 7):
depth: 0 1 2 3 4 5 6 8 9 10
a b c d
e
f
g h i
j
k
It should be easy enough to generate this grid, with either breadth-first or depth-first searches. Perhaps most trivially by simply keeping a 2D array and placing every significant node found into it, inserting a row for every "second child".
Now, knowing these facts:
The last node in a row must be an end node
Children are always to the right, and on the same row or lower, of their parent node.
All non-end nodes must have exactly two children
Therefore, all non-end nodes have children that are the first to the right of their column, the first child being on the same row, the second child being n rows below them, where n is the number of nodes on the right side of it.
We can see that, given any valid grid, there is one unambiguous way to "connect the dots", so to speak; there is one unambiguous tree being represented.
Now, the "connecting the dots" is no longer a binary-tree-structure question...it's simply a decoration question. We just need to build an algorithm to properly place the right -'s and \'s where they can go, perhaps following only simple grid/lexicographical rules, instead of binary-tree-structure rules.
Basically, this means that the problem of rendering a tree is now the much simpler problem of rendering a grid, with fancy decorations.
Can anyone suggest any way of formulating these rules? Or maybe a completely different method altogether?
edit
I have conceived of a much, much easier final rendering:
--d0----d1----d3----d4----d5----d6----d8----d9----d10-- => guide line (not rendered)
[a0 ]-------[b3 ]-------[c5 ]-------[d8 ]
| | \---------------[e9 ]
| \---------[f5 ]
\---[g1 ]-------[h4 ]-------[i6 ]
| \---------------------------[j10]
\---[k3 ]
--d0----d1----d3----d4----d5----d6----d8----d9----d10-- => guide line (not rendered)
It might be easier to try to create this one, instead of the one I had posted earlier. For one, it preserves a pretty grid shape, and you don't have to fickle with diagonal lines. The rows are all mapped along clearly visible column lines. Unfortunately, it is nowhere near as pretty as the first.
If there are N end nodes, there must be N-1 internal nodes with 2 children. (There can be any number of internal nodes with 1 child, which we will have to count to get the depths but otherwise ignore.) Generating the tree is thus equivalent to positioning these nodes on a grid, where:
the number of rows in the grid is N
I think the number of columns is between 1+floor(log2(N)) and 2*N-1, depending on how much overlap there is; this probably doesn't matter much for our purposes, though
each endpoint appears on a different row
all nodes at the same depth appear in the same column
all internal nodes appear on the same row as their rightmost descendant endpoint
So, let's see:
Walk the tree depth-first, right-to-left.
For each endpoint, record its depth and label.
For each 2-child internal, record its depth, label and the indices of both rightmost and leftmost child endpoints.
Sort the whole lot by depth -- this gives you the column ordering, with the number of distinct depths giving the actual number of columns. (All other ordering should come out automatically from the walk, I think, but that's not the case here because any branch can be any depth.)
Place all the nodes in the grid.
Mark empty cells to the right of each non-endpoint node as horizontal branches.
Mark empty cells down from each internal node to the row above its left child as vertical branches, and the cell at the level of the left child as a junction.
Print with appropriate ASCII decoration.
Update:
As you say, the positioning is enough to unambiguously determine the connections, but you still need to do some bottom-up work to get that right, so I'd probably still do the "mark" steps during the grid building.
I sort of thought the printing was trivial enough to gloss over, but:
Iterate down each column and determine the column width as size of fixed elements + max label length + floor(log10(depth) + 1). (Fixed elements might be [ and ]-, for example. We can substitute ]\n as the suffix for endpoints.)
For each row
for each column
if cell contains a node or endpoint
print fixed prefix
print label
print depth
print fill spaces (max label length - current label length)
print appropriate suffix
if node is an endpoint, skip to next row
if cell is empty, print fill spaces to width of column
if cell contains a vertical, print some chosen prefix number of spaces, a bar, and fill with spaces
if cell contains a junction, print some chosen prefix number of spaces, a backslash, and fill with hyphens
if cell contains a horizontal, print full column width of hyphens
Converting this to print diagonals might be easiest if you generate the straight version first and then do some substitutions in the character array -- otherwise you can get cases where you're rendering a long vertical branch in a different column than the one in which it originated.
At some point I may try to put this into code, but it probably won't be today -- stuff to do!
Looks like an interesting problem; I'd be happy to give it a try, if I had more time.
I'd probably go with the following approach :
Start rendering "right" (or in your case, "top") nodes, until I reach the end. (i.e.: render a, b, c, and d)
Go back to the last node with a child (i.e.: c), and do the same thing recursively
You would have to keep a global variable indicating on wich row you are printing. Each recursive call increases this variable.
edit: ok, couldn't resist trying to write some untested pseudo-code, hope it works:
function print_tree(Node n) {
print "\n" // begin on a fresh new line
childs = new Array();
do {
if (n.hasLeftChild) {
childs.push(n.leftChild)
}
print "---" + n.id //this needs a lot of tweaking, but you get the idea
} while(n = n.rightChild)
childs.reverse()
foreach(child in childs) {
print_tree(child);
}
}
If you start with a label width for each level (not including [] characters), equal to the largest label for that width (in this example the widths are mostly 2 except j10 which is 3, and levels 2 and 7 which are 0).
Have each level with non-zero max label width equally spaced with one - character between each level, so you can calculate initial level y locations.
Give each node it's line number.
Then adjust the level locations based on the maximum number of lines between children for a level.
Added 2 to level 1 for a0 to g1
Added 1 to level 2 for g1 to k3
Added 1 to level 4 for b3 to [ ]
Use \ and ` characters for diagonals.
[a0]---------[b3]-------[c5]------[d8]
\ \ `----------[e9]
\ `-----[f5]
`[g1]--------[h4]------[i6]
\ `--------------------[j10]
`[k3]
Below is fully functional C# code that does exactly what you want. How it does it:
The tree is represented as objects from classes that inherit from Node
First compute the number of leaves and create an array of that much lines
Then for each level:
find out on what lines are we going to write
for those lines, compute the maximum of what is already on those lines
write the all the nodes to column max(number from previous step, end of previous level)+1; prepend with - to get to that column
write diagonal lines from all binary nodes up to the line of their right child (in my program first child is left, second is right, you have it the other way around)
advance one level
The algorithm makes sure that each level starts only after previous ends. That is probably good choice for short names, but for longer names, this probably shouldn't be enforced.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SO_ASCII_tree
{
class Program
{
static void Main()
{
Node root = …;
StringBuilder[] lines = Enumerable.Range(0, root.Leaves).Select(i => new StringBuilder()).ToArray();
Node[] currentLevel = new Node[] { root };
int level = 0;
int min = 0;
int max = 0;
while (currentLevel.Any())
{
NamedNode[] namedNodes = currentLevel.OfType<NamedNode>().ToArray();
if (namedNodes.Any())
{
min = namedNodes.Select(node => lines[node.Line].Length).Max();
min = Math.Max(min, max);
if (min != 0)
min++;
foreach (NamedNode namedNode in namedNodes)
WriteAtPosition(lines[namedNode.Line], namedNode.Write(level), min, '-');
max = namedNodes.Select(node => lines[node.Line].Length).Max();
// change to max = min + 1; for long names
}
foreach (Node node in currentLevel)
node.SetChildLines();
Binary[] binaries = namedNodes.OfType<Binary>().ToArray();
foreach (Binary binary in binaries)
GoDown(lines, binary.Line, binary.Right.Line);
currentLevel = currentLevel.SelectMany(node => node.Children).ToArray();
level++;
}
foreach (StringBuilder line in lines)
Console.WriteLine(line.ToString());
}
static void WriteAtPosition(StringBuilder line, string message, int position, char prepend = ' ')
{
if (line.Length > position)
throw new ArgumentException();
line.Append(prepend, position - line.Length);
line.Append(message);
}
static void GoDown(StringBuilder[] lines, int from, int to)
{
int line = from + 1;
int position = lines[from].Length;
for (; line <= to; line++, position++)
WriteAtPosition(lines[line], "\\", position);
}
}
abstract class Node
{
public int Line
{ get; set; }
public abstract int Leaves
{ get; }
public abstract IEnumerable<Node> Children
{ get; }
public virtual void SetChildLines()
{ }
}
abstract class NamedNode : Node
{
public string Name
{ get; set; }
public string Write(int level)
{
return '[' + Name + level.ToString() + ']';
}
}
class Binary : NamedNode
{
public Node Left
{ get; set; }
public Node Right
{ get; set; }
int? leaves;
public override int Leaves
{
get
{
if (leaves == null)
leaves = Left.Leaves + Right.Leaves;
return leaves.Value;
}
}
public override IEnumerable<Node> Children
{
get
{
yield return Left;
yield return Right;
}
}
public override void SetChildLines()
{
Left.Line = Line;
Right.Line = Line + Left.Leaves;
}
}
class Unary : Node
{
public Node Child
{ get; set; }
int? leaves;
public override int Leaves
{
get
{
if (leaves == null)
leaves = Child.Leaves;
return leaves.Value;
}
}
public override IEnumerable<Node> Children
{
get
{
yield return Child;
}
}
public override void SetChildLines()
{
Child.Line = Line;
}
}
class Leaf : NamedNode
{
public override int Leaves
{
get
{
return 1;
}
}
public override IEnumerable<Node> Children
{
get
{
yield break;
}
}
}
}
EDIT: Your example tree gets rendered exactly the same as your rendering:
[a0]-----------[b3]------[c5]------[d8]
\ \ \----------[e9]
\ \----[f5]
\-[g1]--------[h4]------[i6]
\ \--------------------[j10]
\-[k3]
You'd probably need to perform a depth first search if not a search of the entire tree in order to properly size it for output along 2 dimensions.

Resources