이진 탐색 트리의 특징
그냥 왼쪽 왕작다 오른쪽 왕크다로 생각해요.

21이 루트 노드이고, 다음으로 28을 트리에 삽입할 때 21보다 큰 값이므로 오른쪽으로 간다.
그 다음 값인 14는 21보다 작으므로 왼쪽으로 간다.

class Node:
def __init__(self,data):
self.data = data
self.left = None
self.right = None
class BinarySearchTree:
def __init__(self):
self.root = None
def insert(self,data):
if self.root is None:
self.root = Node(data)
else:
self._insert_recursive(self.root,data)
def _insert_recursive(self, root, data):
if data < root.data:
if root.left is None:
root.left = Node(data)
else:
self._insert_recursive(root.left,data)
elif data> root.data:
if root.right is None:
root.right = Node(data)
else:
self._insert_recursive(root.right,data)
_insert_recursive 메서드를 호출하여 재귀적으로 삽입을 수행합니다.왼쪽 서브트리로 이동합니다.오른쪽 서브트리로 이동합니다 def delete(self,value):
self.root = self._delete_recursive(self.root,value)
def _delete_recursive(self,root,value):
if root is None:
return root
if value < root.data:
root.left = self._delete_recursive(root.left,value)
elif value > root.data:
root.right = self._delete_recursive(root.right,value)
else:
if root.left is None:
return root.right
elif root.right is None:
return root.left
root.data = self._get_min_value(root.right)
root.right = self._delete_recursive(root.right,root.data)
return root
def _get_min_value(self,root):
while root.left is not None:
root = root.left
return root.data
왼쪽 서브트리에서 값을 삭제하도록 재귀 호출합니다.오른쪽 서브트리에서 값을 삭제하도록 재귀 호출합니다.오른쪽 자식을 반환하여 현재 노드의 자리를 대체합니다.왼쪽 자식을 반환하여 마찬가지로 현재 노드의 자리를 대체합니다.오른쪽 서브트리에서 가장 작은 값을 찾아 현재 노드의 데이터를 그 값으로 대체하고, 오른쪽 서브트리에서 그 값을 삭제합니다.while root.left is not None 은 현재 노드의 왼쪽 자식이 None이 아닌 동안 계속 반복하여 왼쪽 자식으로 이동합니다. def search(self,value):
return self._search_recursive(self.root, value)
def _search_recursive(self, root, value):
if root is None or root.data == value:
return root
if value < root.data:
return self._search_recursive(root.left,value)
return self._search_recursive(root.right,value)
search 메서드는 BST에서 주어진 값(value)를 찾기 위해 _serach_recursive 메서드를 호출합니다.
여기서 매개변수 value는 BST에서 찾고자 하는 값입니다
search_recursive는 실제 재귀적으로 BST를 탐색하여 주어진 값(value)을 찾습니다.
root는 현재 서브 트리의 루트 노드입니다. 초기에는 BST의 전체 루트(self.root)로 시작하며, 재귀 호출 시 해당 서브트리의 루트로 갱신됩니다. value는 위와 동일하게 찾고자 하는 값입니다.
root가 None인 경우 BST가 비어 있거나 해당 값을 가진 노드를 찾지 못한 경우 -> 이 경우 None을 반환합니다 or root.data == value 인 경우 해당 노드의 데이터가 찾는 값과 일치하는 경우 -> 해당 노드를 반환합니다.
value < root.data 인 경우 : 찾고자 하는 값이 현재 노드의 데이터보다 작으므로, 왼쪽 자식 노드에서 재귀적으로 탐색을 진행합니다.
그 외의 경우 (value > root.data) : 찾고자 하는 값이 현재 노드의 데이터보다 크거나 같으므로, 오른쪽 자식 노드에서 재귀적으로 탐색을 진행합니다.
_search_recursive 메서드는 재귀적인 방식으로 동작하여, 현재 노드의 데이터와 찾고자 하는 값(value)을 비교합니다.
재귀 호출을 통해 각 서브트리에서도 동일한 비교와 탐색 작업을 수행하며 BST의 특성에 따라 왼쪽 또는 오른쪽 자식 노드로 이동합니다.
def preorder_traversal(self):
result = []
self._preorder_recursive(self.root, result)
return result
def _preorder_recursive(self, root, result):
if root is not None:
result.append(root.data)
self._preorder_recursive(root.left, result)
self._preorder_recursive(root.right, result)
전위 순회는 루트 노드를 먼저 방문한 후 왼쪽 서브트리를 순회하고, 그 다음에 오른쪽 서브트리를 순회하는 방식입니다.
preorder_traversal 메서드는 이진 트리의 전위 순회 결과를 반환합니다.
변수 result 는 전위 순회 결과를 저장하는 리스트입니다.
전위 순회를 수행한 결과인 result 리스트를 반환합니다.
_preorder_recursive 메서드는 재귀적으로 이진 트리를 전위 순회합니다.
매개변수는 위와 비슷합니다.
root: 현재 순회하고 있는 서브트리의 루트 노드입니다. 초기에는 전체 트리 의 루트(self.root)로 시작하며, 재귀 호출 시에는 순회 중인 서브트리의 루트가 됩니다.
result: 전위 순회 결과를 저장할 리스트입니다.
if root is not None : 현재 노드(root)가 None이 아닌지 확인합니다.
None인 경우에는 리프 노드나 자식이 없는 노드입니다. 재귀 호출을 계속하기 전에 이 조건을 확인하여 작업을 중지합니다.
result.append(root.data) : 현재 노드의 데이터를 result 리스트에 추가합니다.
이는 전위 순회의 특성에 따라 먼저 루트 노드를 방문하고 데이터를 처리하는 단계입니다..
self._preorder_recursive(root.left, result): 현재 노드의 왼쪽 자식 노드로 재귀 호출을 수행합니다. 이는 왼쪽 서브트리를 전위 순회하는 과정입니다. 왼쪽 자식이 None이면 해당 부분은 스킵됩니다.
def inorder_traversal(self):
result = []
self._inorder_recursive(self.root, result)
return result
def _inorder_recursive(self, root, result):
if root is not None:
self._inorder_recursive(root.left, result)
result.append(root.data)
self._inorder_recursive(root.right, result)
중위 순회가 전위 순회와의 다른 점은
result.append(root.data) 가
왼쪽 서브트리를 모두 순회한 후 현재 노드를 방문한다는 것입니다.
def postorder_traversal(self):
result = []
self._postorder_recursive(self.root, result)
return result
def _postorder_recursive(self, root, result):
if root is not None:
self._postorder_recursive(root.left, result)
self._postorder_recursive(root.right,result)
result.append(root.data)
result.append(root.data)가
왼쪽 서브트리를 후위 순회한 뒤에 오른쪽 서브트리를 후위 순회하고,
마지막으로 루트 노드를 방문하게 됩니다.