-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbinary-search-tree.py
200 lines (141 loc) · 3.87 KB
/
binary-search-tree.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
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
# A utility function to insert
# a new node with the given key
def insert(root, key):
if root is None:
return Node(key)
if root.val == key:
return root
if root.val < key:
root.right = insert(root.right, key)
else:
root.left = insert(root.left, key)
return root
# A utility function to do inorder tree traversal
def search(root, key):
# Base Cases: root is null or key is present at root
if root is None or root.val == key:
return root
# Key is greater than root's key
if root.val < key:
return search(root.right, key)
# Key is smaller than root's key
return search(root.left, key)
def is_in_tree(root, key):
return search(root, key) is not None
def inorder(root):
if root:
inorder(root.left)
print(root.val)
inorder(root.right)
def deleteNode(root, key):
# Base Case
if root is None:
return root
# Recursive calls for ancestors of
# node to be deleted
if key < root.key:
root.left = deleteNode(root.left, key)
return root
if key > root.key:
root.right = deleteNode(root.right, key)
return root
# We reach here when root is the node
# to be deleted.
# If one of the children is empty
if root.left is None:
temp = root.right
root = None
return temp
if root.right is None:
temp = root.left
root = None
return temp
# If both children exist
succParent = root
# Find Successor
succ = root.right
while succ.left is not None:
succParent = succ
succ = succ.left
# Delete successor.Since successor
# is always left child of its parent
# we can safely make successor's right
# right child as left of its parent.
# If there is no succ, then assign
# succ->right to succParent->right
if succParent != root:
succParent.left = succ.right
else:
succParent.right = succ.right
# Copy Successor Data to root
root.key = succ.key
return root
def minValue(node):
current = node
# loop down to find the lefmost leaf
while current.left is not None:
current = current.left
return current.val
def maxValue(node):
current = node
# loop down to find the lefmost leaf
while current.right is not None:
current = current.right
return current.val
def get_height(node):
if node is None:
return -1
# Compute the depth of each subtree
lDepth = get_height(node.left)
rDepth = get_height(node.right)
# Use the larger one
if lDepth > rDepth:
return lDepth + 1
return rDepth + 1
INT_MAX = 4294967296
INT_MIN = -4294967296
# Returns true if the given tree is a binary search tree
# (efficient version)
def isBST(node):
return isBSTUtil(node, INT_MIN, INT_MAX)
# Retusn true if the given tree is a BST and its values
# >= min and <= max
def isBSTUtil(node, mini, maxi):
# An empty tree is BST
if node is None:
return True
# False if this node violates min/max constraint
if node.val < mini or node.val > maxi:
return False
# Otherwise check the subtrees recursively
# tightening the min or max constraint
return isBSTUtil(node.left, mini, node.val - 1) and isBSTUtil(
node.right, node.val + 1, maxi
)
# Driver rogram to test the above functions
# Let us create the following BST
# 50
# / \
# 30 70
# / \ / \
# 20 40 60 80
r = Node(50)
r = insert(r, 30)
r = insert(r, 20)
r = insert(r, 40)
r = insert(r, 70)
r = insert(r, 60)
r = insert(r, 80)
# Print inoder traversal of the BST
inorder(r)
print(is_in_tree(r, 30))
print(is_in_tree(r, 100))
print(get_height(r))
print(minValue(r))
print(maxValue(r))
print(isBST(r))