From 7f7d1bdf24f38f66f4de19a04e108a1e4de01999 Mon Sep 17 00:00:00 2001 From: bt3gl <138340846+bt3gl-google@users.noreply.github.com> Date: Sun, 30 Jul 2023 11:57:17 -0700 Subject: [PATCH] Create hash_set_bst.py --- arrays_and_strings/hash_set_bst.py | 101 +++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 arrays_and_strings/hash_set_bst.py diff --git a/arrays_and_strings/hash_set_bst.py b/arrays_and_strings/hash_set_bst.py new file mode 100644 index 0000000..3955a23 --- /dev/null +++ b/arrays_and_strings/hash_set_bst.py @@ -0,0 +1,101 @@ +class HashSet: + + def __init__(self): + self.key_range = 131 + self.bucket = [Bucket() for _ in range(self.key_range)] + + def _hash(self, key): + return key % self.key_range + + def add(self, element: int) -> None: + bucket_index = self._hash(element) + self.bucket[bucket_index].insert(element) + + def remove(self, element: int) -> None: + bucket_index = self._hash(element) + self.bucket[bucket_index].delete(element) + + def contains(self, element: int) -> bool: + bucket_index = self._hash(element) + return self.bucket[bucket_index].exists(element) + + +class TreeNode: + def __init__(self, value=None): + self.val = value + self.left = None + self.right = None + + +class Bucket: + def __init__(self): + self.tree = BSTree() + + def insert(self, value): + self.tree.root = self.tree.insert(self.tree.root, value) + + def delete(self, value): + self.tree.root = self.tree.delete(self.tree.root, value) + + def exists(self, value): + return (self.tree.search(self.tree.root, value) is not None) + + +class BSTree(): + def __init__(self): + self.root = None + + def search(self, root, value) -> TreeNode: + if root is None or value == root.val: + return root + + return self.search(root.left, value) if val < root.value \ + else self.search(root.right, value) + + def insert(self, root, value) -> TreeNode: + if not root: + return TreeNode(value) + + if value > root.val: + root.right = self.insert(root.right, value) + elif value == root.val: + return root + else: + root.left = self.insert(root.left, value) + + def successor(self, root): + # one step right and then all left + root = root.right + while root.left: + root = root.left + return root.value + + def predecessor(self, root): + # one step left and then always right + root = root.left + while root.right: + root = root.right + return root.value + + def delete(self, root, key) -> TreeNode: + if not root: + return None + + if key > root.val: + root.right = self.delete(root.right, key) + + elif key < root.val: + root.left = self.delete(root.left, key) + + else: + if not (root.left or root.right): + root = None + elif root.right: + root.val = self.sucessor(root) + root.right = self.delete(root.right, root.val) + else: + root.val = self.predecessor(root) + root.left = self.delete(root.left, root.val) + + return root +