-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinary_tree.py
More file actions
155 lines (124 loc) · 4 KB
/
Copy pathbinary_tree.py
File metadata and controls
155 lines (124 loc) · 4 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#! /usr/bin/env python
"""Binary tree.
"""
class ChildlessError(Exception):
def __init__(self, node_name):
super(ChildlessError, self).__init__(
'The {} Node instance have no children.'.format(node_name))
class Node(object):
"""Base node class."""
data = left = right = None
def __init__(self, data=None):
self.data = data
def __lt__(self, other):
return self.data < other
def __gt__(self, other):
return self.data > other
def __eq__(self, other):
return self.data == other
def __repr__(self):
return "<{}.{}({}) object at {}>".format(
self.__class__.__module__,
self.__class__.__name__,
self.data,
hex(id(self)))
def insert(self, value):
"""Add new node with given value to a tree."""
if self.data == None:
self.data = value
else:
if self < value:
if not self.right:
self.right = Node()
child = self.right
else:
if not self.left:
self.left = Node()
child = self.left
if child:
return child.insert(value)
else:
child = Node(value)
def lookup(self, value, entry=None):
"""Search for particular value from existing nodes below the node."""
entry = entry or self
if value == entry:
return entry
child = self.right if self < value else self.left
return child and child.lookup(value, child) or None
def delete(self, value):
"""Node deletion and further regroup."""
if self == value:
if self.right:
child = self.right
relative = None
while child.left:
relative = child
child = child.left
self.data = child.data
child.right and self.right.insert(child.right.data)
if relative:
relative.left = None
else:
self.right = None
elif self.left:
self.data = self.left.data
self.right = self.left.right
self.left = self.left.left
else:
raise ChildlessError
else:
child = self.right if self < value else self.left
if child:
child.delete(value)
else:
raise LookupError
class BTree(object):
"""Base binary tree class.
::root: Node instance, entry point to all the tree operations.
::current: list of nodes, describes tree level. Nedded for iteration.
"""
root = None
current = None
def __init__(self, *args):
for i in args:
self.insert(i)
def __str__(self):
string = ""
for i in self:
string += str(i)
return string
def __iter__(self):
return self
def next(self):
"""Returns next downwardly tree level every next iteration."""
if not self.current:
self.current = [self.root,]
return self.current
nc = []
for i in self.current:
if i:
i.left and nc.append(i.left)
i.right and nc.append(i.right)
self.current = nc
if self.current:
return self.current
raise StopIteration
def insert(self, other):
if self.root == None:
self.root = Node(other)
else:
self.root.insert(other)
return self
def lookup(self, value):
try:
return self.root.lookup(value)
except AttributeError:
raise LookupError("{} has no {} item".format(
self.__class__, value))
def delete(self, value):
try:
self.root.delete(value)
except ChildlessError:
self.root = None
return self