Lecture 1 (Binary Search Tree Concepts)¶
Definition¶
- BST : left child < node < right child
- No duplicates allowed
- If duplicates , freq is saved in node.val
- H = log (N)
In [ ]:
### Helpers
In [2]:
from collections import deque
class Node:
def __init__(self,val=0,left=None,right=None):
self.val = val
self.left = left
self.right = right
def to_tree(nums):
n = len(nums)
if n ==0:
return None
root = Node(nums[0])
queue = deque([root])
idx =1
while queue:
node = queue.popleft()
# left child
if idx <n:
val = nums[idx]
if val !=-1:
node.left = Node(val)
queue.append(node.left)
idx +=1
# right child
if idx <n:
val = nums[idx]
if val != -1:
node.right = Node(val)
queue.append(node.right)
idx +=1
return root
root = to_tree([1,2,3,-1,5])
print(root)
<__main__.Node object at 0x109af4610>
Search in a Binary Search Tree¶
Input : [8,5,12,4,7,10,14,-1,-1,6,-1,-1,-1,13] , Kep = 10
Output : True
Input : [4,2,6,1,3,5,7] , Key = 0
Output : False
Approach 1 (Brute Force)¶
- Search all the nodes via dfs
In [5]:
def search(root,target):
if root is None:
return False
if root.val == target:
return True
return search(root.left,target) or search(root.right,target)
print(search(to_tree([8,5,12,4,7,10,14,-1,-1,6,-1,-1,-1,13]),10))
print(search(to_tree([4,2,6,1,3,5,7]),0))
True False
Complexity¶
- N : no of nodes in BST
- O(N)
- O(log N)
Approach 2¶
- Use property of bst
- every iteration eliminate first half
In [6]:
def search(root,target):
if root is None:
return False
if root.val == target:
return True
if root.val < target:
return search(root.right,target)
return search(root.left,target)
print(search(to_tree([8,5,12,4,7,10,14,-1,-1,6,-1,-1,-1,13]),10))
print(search(to_tree([4,2,6,1,3,5,7]),0))
True False
Complexity¶
- N : no of nodes in binary tree
- O(log N)
- O(log N)