-
Notifications
You must be signed in to change notification settings - Fork 34
/
reingold_naive.py
103 lines (76 loc) · 2.38 KB
/
reingold_naive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from gen import Tree, gentree
from operator import lt, gt
from sys import stdout
class DrawTree:
def __init__(self, tree, depth=-1):
self.x = -1
self.y = depth
self.tree = tree
self.children = []
# traverse to the bottom of the tree, and place the leaves at an arbitrary
# x coordinate
# if the node is a parent, draw its subtrees, then shift the right one as close
# to the left as possible
# place the parent in the middle of the two trees.
def reingold_tilford(tree, depth=0):
dt = DrawTree(tree, depth)
if len(tree) == 0:
dt.x = 0
return dt
if len(tree) == 1:
dt.children = [reingold_tilford(tree[0], depth + 1)]
dt.x = dt.children[0].x
return dt
left = reingold_tilford(tree[0], depth + 1)
right = reingold_tilford(tree[1], depth + 1)
dt.children = [left, right]
dt.x = fix_subtrees(left, right)
return dt
# place the right subtree as close to the left subtree as possible
def fix_subtrees(left, right):
wl = contour(left, lt)
wr = contour(right, gt)
diff = max(map(lambda x, y: x - y, wl, wr)) + 1
# stick to the integers
diff += (right.x + diff + left.x) % 2
addtotree(right, diff)
return (left.x + right.x) / 2
def addtotree(tree, val):
tree.x += val
if len(tree.children):
for child in tree.children[:2]:
addtotree(child, val)
def contour(tree, comp, level=0, cont=None):
if not level:
cont = [tree.x]
elif len(cont) < level + 1:
cont.append(tree.x)
elif comp(cont[level], tree.x):
cont[level] = tree.x
for child in tree.children[:2]:
contour(child, comp, level + 1, cont)
return cont
# given an array of nodes, print them out reasonably on one line
def printrow(level):
x = dict((t.x, t.tree) for t in level)
for i in range(max(x.keys()) + 1):
try:
stdout.write(str(x[i])[:4])
except:
stdout.write(" ")
def p(tree):
level = [tree]
while 1:
newlevel = []
printrow(level)
for t in level:
# stdout.write("%s%s%s" % (t.x*"____", str(t)[:3], t.x))
newlevel.extend(t.children[:2])
print
if not newlevel:
break
level = newlevel
# root = gentree("/Users/llimllib/Movies")
# root.children.reverse()
# drawtree = reingold_tilford(root)
# p(drawtree)