def test_get_withKeyInBST_shouldReturnAssociatedValue(self): bst = AVLTree() bst.put("A", 1) bst.put("B", 2) bst.put("C", 3) bst.put("D", 4) self.assertEqual(1, bst.get("A")) self.assertEqual(2, bst.get("B")) self.assertEqual(3, bst.get("C")) self.assertEqual(4, bst.get("D"))
def test_get_withCompareFunctionAndKeyInBST_shouldReturnAssociatedValue( self): bst = AVLTree(self.cmp) bst.put([0, 0], 1) bst.put([0, 1], 2) bst.put([0, 2], 3) bst.put([0, 3], 4) self.assertEqual(1, bst.get([0, 0])) self.assertEqual(2, bst.get([0, 1])) self.assertEqual(3, bst.get([0, 2])) self.assertEqual(4, bst.get([0, 3]))
def test_put_withCompareFunctionAndKeyInBSTAndValueNotNone_shouldReplaceAssociatedValueByNewOneAndNotModifyBSTLength( self): bst = AVLTree(self.cmp) bst.put([0, 0], 0) self.assertEqual(1, len(bst)) self.assertEqual(0, bst.get([0, 0])) bst.put([0, 0], 1) self.assertEqual(1, len(bst)) self.assertEqual(1, bst.get([0, 0])) bst.put([0, 0], 12) self.assertEqual(1, len(bst)) self.assertEqual(12, bst.get([0, 0]))
def test_put_withKeyInBSTAndValueNotNone_shouldReplaceAssociatedValueByNewOneAndNotModifyBSTLength( self): bst = AVLTree() bst.put("A", 0) self.assertEqual(1, len(bst)) self.assertEqual(0, bst.get("A")) bst.put("A", 1) self.assertEqual(1, len(bst)) self.assertEqual(1, bst.get("A")) bst.put("A", 12) self.assertEqual(1, len(bst)) self.assertEqual(12, bst.get("A"))
def test_get_withCompareFunctionANdKeyNotInBST_shouldReturnNone(self): bst = AVLTree(self.cmp) bst.put([0, 1], 0) self.assertIsNone(bst.get([0, 0]))
def test_get_withKeyNotInBST_shouldReturnNone(self): bst = AVLTree() bst.put("A", 0) self.assertIsNone(bst.get("B"))
class StackFR: class Node: def __init__(self, type, value): self.type = type self.value = value def __init__(self): self.__top = None self.__op = Tree() self.__push = AVLTree() self.__pop = AVLTree() self.__cur_time = 0 def top(self, time=None): if time is None or time >= self.__cur_time: time = self.__cur_time time = self.__op.floor(time) if time is None: return None operation = self.__op[time] if operation.type == "PUSH": return operation.value operation = self.__op.find_bridge_before(time) if operation: return self.__op[operation].value return None def push(self, val, time): if val is None or \ time is None: raise ValueError("Invalid argument of None Type") self.__check_time(time) if self.__update_time(time): self.__top = val self.__push.put(time, val) self.__op.put(time, self.Node("PUSH", val), 1) def delete(self, time): if time is None: raise ValueError("Invalid 'time' argument of None Type") self.__op.delete(time) if time in self.__push: self.__push.delete(time) elif time in self.__pop: self.__pop.delete(time) else: raise ValueError("'time' argument does " "not correspond to any operation") self.__top = self.top(self.__cur_time) def pop(self, time): self.__check_time(time) self.__update_time(time) self.__op.put(time, self.Node("POP", time), -1) self.__pop.put(time, time) def size(self, time=None): if time is None: time = self.__cur_time size = self.__push.rank(time) - self.__pop.rank(time) if time in self.__push: size += 1 elif time in self.__pop: size -= 1 if size < 0: return 0 return size def print(self, time=None): if time is None: time = self.__cur_time if self.size(time) == 0: return "[]" res = [] pushes = self.__push.keys_in_order() pops = self.__pop.keys_in_order() ipu = 0 ipo = 0 if self.__pop.empty(): for key in pushes: if key <= time: res.insert(0, self.__push.get(key)) return str(res) change = True while change: change = False if pushes[ipu] < pops[ipo]: res.insert(0, self.__push.get(pushes[ipu])) change = True if ipu + 1 < len(pushes): ipu += 1 else: res.pop(0) change = True if ipo + 1 < len(pops): ipo += 1 return str(res) def __check_time(self, time): if time is None: raise ValueError("Invalid argument 'time' of None Type") if time in self.__push or \ time in self.__pop: raise ValueError("Given 'time' is already in use") def __update_time(self, time): if time >= self.__cur_time: self.__cur_time = time return True return False
class QueueFR: def __init__(self): self.__back = None self.__front = None self.__te = AVLTree() self.__td = AVLTree() self.__cur_time = 0 def front(self, time=None): if time is None: return self.__front if self.size(time) == 0: return None if self.__td.empty(): return self.__te.get(self.__te.min()) time = self.__td.floor(time) if time is None: return self.__te.get(self.__te.select(0)) d = self.__td.rank(time) return self.__te.get(self.__te.select(d + 1)) def back(self, time=None): if time is None: return self.__back if self.__te.empty(): return None if self.size(time) == 0: return None time = self.__te.floor(time) if time is None: return None rank = self.__te.rank(time) return self.__te.get(self.__te.select(rank)) def enqueue(self, val, time): if val is None or \ time is None: raise ValueError("Invalid argument of None Type") self.__check_time(time) if self.__update_time(time): self.__back = val if self.size() == 0: self.__front = self.__back self.__te.put(time, val) def delete(self, time): if time is None: raise ValueError("Invalid 'time' argument of None Type") if time in self.__te: self.__te.delete(time) elif time in self.__td: self.__td.delete(time) else: raise ValueError("'time' argument does " "not correspond to any operation") self.__back = self.back(self.__cur_time) self.__front = self.front(self.__cur_time) def dequeue(self, time): self.__check_time(time) self.__td.put(time, time) d = self.__td.rank(time) res = self.__te.get(self.__te.select(d)) if self.__update_time(time): size = self.size() if size == 0: self.__back = None self.__front = None elif size == 1: self.__front = self.__back else: self.__front = self.__te.get(self.__te.select(d + 1)) return res def print(self, time=None): if time is None: time = self.__cur_time if self.size(time) == 0: return "[]" if self.__td.empty() or \ self.__td.floor(time) is None: front_time = self.__te.min() else: d = self.__td.rank(self.__td.floor(time)) front_time = self.__te.select(d + 1) rank = self.__te.rank(self.__te.floor(time)) back_time = self.__te.select(rank) return str(self.__te.values(front_time, back_time)) def size(self, time=None): if time is None: time = self.__cur_time size = self.__te.rank(time) - self.__td.rank(time) if time in self.__te: size += 1 elif time in self.__td: size -= 1 if size < 0: return 0 return size def __check_time(self, time): if time is None: raise ValueError("Invalid argument 'time' of None Type") if time in self.__te or \ time in self.__td: raise ValueError("Given 'time' is already in use") def __update_time(self, time): if time >= self.__cur_time: self.__cur_time = time return True return False
class MinPQPR: def __init__(self): self.__min = None self.__cur_time = None self.__now = AVLTree() self.__insertion = InsertionTree() self.__updates = PrefixSumBST() def empty(self): return self.__min is None def size(self): return self.__now.size() def __len__(self): return self.size() def min(self): return self.__min def insert(self, key, time): self.__update_time(time) if self.__updates.empty(): self.__now.put(key, time) self.__updates.put(time, key, 0) self.__insertion.put(time, key, True) self.__update_min() return bridge = self.__updates.find_bridge_before(time) bridge = self.__insertion.ceiling(bridge) if bridge: max_now = self.__insertion.max_right(bridge) else: max_now = None if max_now is None: max_k = key else: max_k = max(max_now.val, key) if max_now and max_k == max_now.val: self.__updates.put(time, key, 1) self.__now.put(max_now.val, max_now.key) self.__insertion.put(max_now.key, max_now.val, active=True) else: self.__insertion.put(time, key, active=True) self.__updates.put(time, key, 0) self.__now.put(key, time) self.__update_min() def delete_min(self, time): self.__updates.put(time, "delete-min", -1) if self.__insertion.empty(): self.__update_time(time) return None if self.__update_time(time): min_k = self.__min min_t = self.__now.get(min_k) self.__now.delete_min() self.__update_min() self.__insertion.put(min_t, min_k, False) return min_k bridge = self.__updates.find_bridge_after(time) bridge = self.__insertion.floor(bridge) min_now = self.__insertion.min_left(bridge) self.__insertion.put(min_now.key, min_now.val, False) self.__now.delete(min_now.val) self.__update_min() return min_now.val def delete(self, time): if time is None: raise ValueError("Invalid 'time' argument of None Type") if time not in self.__updates: raise ValueError("'time' argument does " "not correspond to any operation") if self.__updates.get(time) == "delete-min": bridge = self.__updates.find_bridge_before(time) bridge = self.__insertion.ceiling(bridge) max_now = self.__insertion.max_right(bridge) self.__now.put(max_now.val, max_now.key) self.__insertion.put(max_now.key, max_now.val, True) else: bridge = self.__updates.find_bridge_after(time) bridge = self.__insertion.floor(bridge) min_now = self.__insertion.min_left(bridge) self.__now.delete(min_now.val) self.__insertion.delete(min_now.key) self.__updates.delete(time) self.__update_min() def __update_time(self, time): if self.__cur_time is None or \ time >= self.__cur_time: self.__cur_time = time return True return False def __update_min(self): if self.__now.empty(): self.__min = None else: self.__min = self.__now.min()