이진 탐색 트리
이진 탐색을 위한 이진 트리
•
이진 탐색은 데이터 집합이 배열인 경우에만 사용할 수 있기에 이진 탐색을 하기 위해서 데이터 집합의 처음과 끝을 알아야하고, 데이터 집합의 중앙 인덱스를 즉각 계산할 수 있어야 하며, 계산된 중앙 요소에 인덱스로 즉시 접근이 가능해야한다.
•
링크드 리스트는 처음과 끝의 위치는 알고 있어도 중앙 요소는 알 수 없다. 따라서 이진 트리로 이 문제를 해결한다.
from dataclasses import dataclass
@dataclass
class Node:
def __init__(self, data: int):
self.data = data
self.left = None
self.right = None
class BinarySearchTree:
def __init__(self):
self.root = None
def insert(self, data: int):
self.root = self._insert_data(self.root, data)
return self.root is not None
def _insert_data(self, node, data):
if node is None:
node = Node(data)
else:
if data <= node.data:
node.left = self._insert_data(node.left, data)
else:
node.right = self._insert_data(node.right, data)
return node
def delete(self, data):
self.root, deleted = self._delete_data(self.root, data)
return deleted
def _delete_data(self, node, data):
if node is None:
return node, False
deleted = False
if data == node.data:
deleted = True
if node.left and node.right:
parent, child = node, node.right
while child.left is not None:
parent, child = child, child.left
child.left = node.left
if parent != node:
parent.left = child.right
child.right = node.right
node = child
elif node.left or node.right:
node = node.left or node.right
else:
node = None
elif data < node.data:
node.left, deleted = self._delete_data(node.left, data)
else:
node.right, deleted = self._delete_data(node.right, data)
return node, deleted
def find(self, data: int):
return self._find_data(self.root, data)
def _find_data(self, root, data: int):
if root is None or root.data == data:
return root is not None
elif data < root.data:
return self._insert_data(root.left, data)
else:
return self._insert_data(root.right, data)
def preorder_traversal(self):
def _preorder_traversal(root: Node):
if root is None:
pass
else:
print(root.data, end=" ")
_preorder_traversal(root.left)
_preorder_traversal(root.right)
_preorder_traversal(self.root)
def inorder_traversal(self):
def _inorder_traversal(root: Node):
if root is None:
pass
else:
_inorder_traversal(root.left)
print(root.data, end=" ")
_inorder_traversal(root.right)
_inorder_traversal(self.root)
def levelorder_traversal(self):
def _levelorder_traversal(root: Node):
queue = [root]
while queue:
root = queue.pop(0)
if root is not None:
print(root.data, end=" ")
if root.left:
queue.append(root.left)
if root.right:
queue.append(root.right)
_levelorder_traversal(self.root)
Python