from copy import copy, deepcopy
class Node:
def __init__(self, data=None):
self.data = data
self.left = None
self.right = None
def __copy__(self):
new_node = Node(self.data)
if self.left is not None:
new_node.left = copy(self.left)
if self.right is not None:
new_node.right = copy(self.right)
return new_node
def __deepcopy__(self, memo):
if id(self) in memo:
return memo[id(self)]
new_node = Node(self.data)
memo[id(self)] = new_node
new_node.left = deepcopy(self.left, memo)
new_node.right = deepcopy(self.right, memo)
return new_node
class BST:
def __init__(self, values=None):
self.root = None
if isinstance(values, list):
for value in values:
if type(value) == int:
self.insert(value)
else:
raise ValueError("BST chỉ nhận số nguyên")
elif isinstance(values, str):
value = None
for x in values:
if '0' <= x <= '9':
if value is None:
value = 0
value = value * 10 + (ord(x) - ord('0'))
elif x == ' ' or x == ',':
if value is not None:
self.insert(value)
value = None
else:
raise ValueError("Ký tự không hợp lệ")
if value is not None:
self.insert(value)
elif values is None:
self.root = None
else:
raise ValueError("Input không hợp lệ")
def insert(self, value):
self.root = self._insert(self.root, value)
def _insert(self, node, value):
if node is None:
return Node(value)
if value < node.data:
node.left = self._insert(node.left, value)
else:
node.right = self._insert(node.right, value)
return node
def remove(self, value):
self.root = self._remove(self.root, value)
def _remove(self, node, value):
if node is None:
return None
# tìm node cần xóa
if value < node.data:
node.left = self._remove(node.left, value)
elif value > node.data:
node.right = self._remove(node.right, value)
else:
# ===== CASE 1: node lá =====
if node.left is None and node.right is None:
return None
# ===== CASE 2: có 1 con =====
if node.left is None:
return node.right
if node.right is None:
return node.left
# ===== CASE 3: có 2 con =====
successor = self._min(node.right)
node.data = successor.data
node.right = self._remove(node.right, successor.data)
return node
def _min(self, node):
while node.left is not None:
node = node.left
return node
def inorder(self):
self._inorder(self.root)
print()
def _inorder(self, node):
if node is None:
return
self._inorder(node.left)
print(node.data, end=' ')
self._inorder(node.right)
def __copy__(self):
new_bst = BST()
if self.root is not None:
new_bst.root = copy(self.root)
return new_bst
def __deepcopy__(self, memo):
if id(self) in memo:
return memo[id(self)]
new_bst = BST()
memo[id(self)] = new_bst
new_bst.root = deepcopy(self.root, memo)
return new_bst
def __iter__(self):
yield from self._iter_inorder(self.root)
def _iter_inorder(self, node):
if node is None:
return
yield from self._iter_inorder(node.left)
yield node.data
yield from self._iter_inorder(node.right)
def __getitem__(self, key):
values = list(self)
if isinstance(key, slice):
new_values = values[key]
return BST(new_values)
return values[key]
class vector3D(object):
"""docstring for vector3D"""
def __init__(self, x, y, z):
super(vector3D, self).__init__()
self.x = x
self.y = y
self.z = z
def __str__(self):
return f"[{self.x}, {self.y}, {self.z}]"
def __add__(self, other):
if isinstance(other, vector3D):
return vector3D(self.x + other.x, self.y + other.y, self.z + other.z)
else:
return vector3D(self.x, self.y, self.z)
def __radd__(self, other):
return self.__add__(other)
def __neg__(self):
return vector3D(- self.x, - self.y, - self.z)
def __mul__(self, other):
if isinstance(other, vector3D):
return (self.x * other.x) + (self.y * other.y) + (self.z * other.z)
elif isinstance(other, (int, float)):
return vector3D(self.x * other, self.y * other, self.z * other)
else:
return vector3D(self.x, self.y, self.z)
def __rmul__(self, other):
return self.__mul__(other)
def __iter__(self):
return iter(f"{self.x}{self.y}{self.z}")