Skip to content

Commit 13928f5

Browse files
Iterator Patterns
1 parent 4a76369 commit 13928f5

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
class Node:
2+
def __init__(self, value, left=None, right=None):
3+
self.right = right
4+
self.left = left
5+
self.value = value
6+
7+
self.parent = None
8+
9+
if left:
10+
self.left.parent = self
11+
if right:
12+
self.right.parent = self
13+
14+
def __iter__(self):
15+
return InOrderIterator(self)
16+
17+
18+
class InOrderIterator:
19+
def __init__(self, root):
20+
self.root = self.current = root
21+
self.yielded_start = False
22+
while self.current.left:
23+
self.current = self.current.left
24+
25+
def __next__(self):
26+
if not self.yielded_start:
27+
self.yielded_start = True
28+
return self.current
29+
30+
if self.current.right:
31+
self.current = self.current.right
32+
while self.current.left:
33+
self.current = self.current.left
34+
return self.current
35+
else:
36+
p = self.current.parent
37+
while p and self.current == p.right:
38+
self.current = p
39+
p = p.parent
40+
self.current = p
41+
if self.current:
42+
return self.current
43+
else:
44+
raise StopIteration
45+
46+
def traverse_in_order(root):
47+
def traverse(current):
48+
if current.left:
49+
for left in traverse(current.left):
50+
yield left
51+
yield current
52+
if current.right:
53+
for right in traverse(current.right):
54+
yield right
55+
for node in traverse(root):
56+
yield node
57+
58+
59+
60+
if __name__ == '__main__':
61+
# 1
62+
# / \
63+
# 2 3
64+
65+
# in-order: 213
66+
# preorder: 123
67+
# postorder: 231
68+
69+
root = Node(1,
70+
Node(2),
71+
Node(3))
72+
73+
it = iter(root)
74+
75+
print([next(it).value for x in range(3)])
76+
77+
for x in root:
78+
print(x.value)
79+
80+
for y in traverse_in_order(root):
81+
print(y.value)

0 commit comments

Comments
 (0)