이진 탐색 트리의 특징
그냥 왼쪽 왕작다 오른쪽 왕크다로 생각해요.
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)가
왼쪽 서브트리를 후위 순회한 뒤
에 오른쪽 서브트리를 후위 순회
하고,
마지막으로 루트 노드를 방문하게 됩니다.