이진 검색 트리에는 3가지 특징이 있다.
위와 같은 형태가 되는데 보다 싶이 좌측 서브 트리포함 모든 값들은 루트 노드보다 작다.
이렇게 하면 검색도 용이하다.
Python코드로 짜보자면
우선 노드와 트리를 정의한다.
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class BinarySearchTree(object):
def __init__(self):
self.root = None
def treeSearch(root, key):
if root is None || root.key == key:
return root is not None
elif root.key > key:
treeSearch(root.left, key)
else:
treeSearch(root.right, key)
Search실패하면 찾는 값이 없는 것이다.
이번에는 삽입을 해보자
최악의 검색 시간은 Θ(logn)이다.
가장 나쁘게 기울면 평균 검색 시간이 Θ(n)이 된다.
[30, 20, 25, 40, 10, 35]를 순차적으로 삽입한다.
def treeInsert(root, key):
if root is None:
root = Node(key)
elif root.key > key:
treeInsert(root.left, key)
else:
treeInsert(root.right, key)
삽입 역시도 가능한 모든 삽입 순서에 따른 이진 검색 트리를 모두 고려하면 평균 검색 시간은 Θ(logn)이다.
삽입은 실패하는 검색 후 상수 시간의 후처리를 하므로 점근적 수행 시간은 검색과 동일하다.
이진 검색 트리에서 노드 r을 삭제하고자 할 때는 다음 세가지 경우에 따른 각각 다르게 처리를 해주어야 한다.
1과 2는 처리가 간단하지만 3은 비교적 다소 복잡하다.
def treeDelete(root):
if root.left == None and root.right == None: //리프 노드인 경우
root = None
elif root.left == None xor root.right == None: //자식이 하나인 경우
if root.left is None:
root = root.right
else:
root = root.left
else://r의 자식 노드가 두 개인 경우
child = root.left
while(child != None):
child = child.left
root.key = child.key
treeDelete(child)