forked from y-ncao/Python-Study
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbt.py
executable file
·291 lines (247 loc) · 7.28 KB
/
bt.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
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/usr/bin/env python
class tree_node(object):
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def create_minimum_BST(data_list, start, end):
if end < start:
return None
mid = (start + end) / 2
n = tree_node(data_list[mid])
n.left = create_minimum_BST(data_list, start, mid-1)
n.right = create_minimum_BST(data_list, mid+1, end)
return n
def in_order_traverse(root):
if root is None:
return
in_order_traverse(root.left)
print root.data
in_order_traverse(root.right)
def pre_order_traverse(root):
if root is None:
return
print root.data
pre_order_traverse(root.left)
pre_order_traverse(root.right)
def post_order_traverse(root):
if root is None:
return
post_order_traverse(root.left)
post_order_traverse(root.right)
print root.data
def dfs(root):
if root is None:
return
stack = [root,]
while len(stack) > 0:
node = stack.pop()
print node.data
if node.right is not None:
stack.append(node.right)
if node.left is not None:
stack.append(node.left)
from collections import deque
def bfs(root):
if root is None:
return
queue = deque([root])
while len(queue) > 0:
node = queue.popleft()
print node.data
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
def copy_tree(root, new_node):
if root.left is not None:
new_node.left = tree_node(root.left.data)
copy_tree(root.left, new_node.left)
if root.right is not None:
new_node.right = tree_node(root.right.data)
copy_tree(root.right, new_node.right)
return new_node
# Note:
# inorder preorder postorder are all DFS
# if you want to implement inorder, you need to first push right to stack since stack is LIFO
# but in BFS, just use normal left -> right would be fine
def get_height(root):
if root is None:
return 0
return max( get_height(root.left), get_height(root.right)) + 1
def is_balance(root):
if root is None:
return True
if abs(get_height(root.left) - get_height(root.right)) > 1:
return False
return is_balance(root.left) and is_balance(root.right)
def covers(root, p):
if root is None:
return False
if root == p:
return True
return covers(root.left, p) or covers(root.right, p)
# store the result of cover so that we don't need to calculate it again
def first_common_ancestor(root, p, q):
# p q not a child of root
if not (covers(root, p) and covers(root,q)):
return None
p_is_left = covers(root.left, p)
q_is_left = covers(root.left, p)
# Diff sides
if p_is_left != q_is_left:
return root
elif p_is_left:
return first_common_ancestor(root.left, p, q)
else:
return first_common_ancestor(root.right, p, q)
def is_subtree(t1, t2):
if t1 == None:
return False
if t1.data == t2.data:
if is_match(t1, t2):
return True
return is_subtree(t1.left, t2) or is_subtree(t1.right, t2)
def is_match(t1,t2):
if t1 is None and t2 is None:
return True
elif t1 is None or t2 is None:
return False
else:
if t1.data != t2.data:
return False
else:
return is_match(t1.left, t2.left) and is_match(t1.right, t2.right)
def print_path(node, path_list):
path_list.append(node)
if node.left is None and node.right is None:
s = ''
for key in path_list:
s += str(key.data) + ' '
print s
return
if node.left is not None:
print_path(node.left, path_list)
path_list.pop()
if node.right is not None:
print_path(node.right, path_list)
path_list.pop()
def is_full(root):
if root is None:
return True
if root.left is None and root.right is None:
return True
if root.left is None or root.right is None:
return False
return is_full(root.left) && is_full(root.right)
def is_complete(root):
queue = deque([root,])
empty = False
while len(queue) > 0:
n = queue.popleft()
if n.left is None:
empty = True
else:
if empty:
return False
queue.append(n.left)
if n.right is None:
empty = True
else:
if empty:
return False
queue.append(n.right)
return True
def is_symmetry(n1, n2):
if n1 is None and n2 is None:
return True
if n1 is None or n2 is None:
return False
if n1.data != n2.data:
return False
return is_symmetry(n1.left, n2.right) and is_symmetry(n1.right, n2.left)
def is_symmetry(root):
if root is None:
return True
return is_symmetry(root.left, root.right)
def mirrow_tree(root):
if root is None:
return
mirrow_tree(root.left, root.left)
# Consider the case that t1 is None and T2 is not
def mirrow_tree(n1, n2):
if n1 is None or n2 is None:
return
tmp = n1.data
n1.data = n2.data
n2.data = tmp
if n1.left is not None and n2.right is not None:
mirrow_tree(n1.left, n2.right)
if n1.right is not None and n2.left is not None:
mirrow_tree(n1.right, n2.left)
# Not going to add more to here. Just add four more check here
# BFS way
def create_list_level_tree(root):
result = [[root,],]
prev = [root,]
current = []
while len(prev) > 0:
for tree_node in prev:
if tree_node.left is not None:
current.append(tree_node.left)
if tree_node.right is not None:
current.append(tree_node.right)
result.append(current)
prev = current
current = []
return result
# DFS way
def create_list_level_tree(root):
pass
# Check if a BT is a BST, use in-order traverse and copy to a list
def check_bst(root):
bst_list = []
def copy_bst(root):
if root is None:
return
copy_bst(root.left)
bst_list.append(root)
copy_bst(root.right)
prev = bst_list[0]
for node in bst_list[1:]:
if prev.data >= node.data:
return False
else:
prev = node
return True
# Use a left node < current < right node
def check_bst(root, min_value, max_value):
if root is None:
return True
if root.data < min_value or root.data > max_value:
return False
if not check_bst(root.left, min_value, root.data) or not check_bst(root.right, root.data, max_value):
return False
return True
def get_rank(root, num):
pass
def tree_diameter(root, num):
pass
if __name__ == '__main__':
data_list = [1,3,4,5,6,8,9,10,13,14,17,18]
root = create_minimum_BST(data_list, 0, len(data_list)-1)
print root.data,root.left.data,root.right.data
print '\nIn Order Traverse'
in_order_traverse(root)
print '\nPre Order Traverse'
pre_order_traverse(root)
print '\Post Order Traverse'
post_order_traverse(root)
print '\nDFS'
dfs(root)
print '\nBFS'
bfs(root)
#print '\nCopy Tree'
print '\nPrint Path'
path_list = []
print_path(root, path_list)