트리(Tree)란?
- 노드(Node)와 브랜치(Branch)를 이용하여 사이클을 이루지 않도록 구성한 데이터 구조이다.
- 트리 중 이진 트리(Binary Tree) 형태의 구조로 탐색 알고리즘 구현을 위해 많이 사용된다.
용어
- 노드(Node): 트리에서 데이터를 저장하는 기본 요소이다.(데이터와 다른 연결된 노드에 대한 브랜치 정보를 포함한다.)
- 루트 노드(Root Node): 트리 맨 위에 있는 노드이다.
- 레벨(Level): 최상위 노드를 레벨 0으로 하였을 때, 하위 브랜치로 연결된 노드의 깊이를 나타낸다.
- 부모 노드(Parent Node): 어떤 노드 다음 레벨에 연결된 노드이다.
- 자식 노드(Child Node): 어떤 노드의 상위 레벨에 연결된 노드이다.
- 리프 노드(Leaf Node, Terminal Node): 자식 노드가 하나도 없는 노드이다.
- 형제 노드(Brother Node, Sibling): 동일한 부모 노드를 가진 노드이다.
- 깊이(Depth): 트리에서 노드가 가질 수 있는 최대 레벨이다.
이진 트리와 이진 탐색 트리(Binary Search Tree)
- 이진 트리: 노드의 최대 브랜치가 2인 트리이다.
- 이진 탐색 트리(BST, Binary Search Tree): 이진 트리에 추가적인 조건이 있는 트리이다.
- 왼쪽 노드는 해당 노드보다 작은 값, 오른쪽 노드는 해당 노드보다 큰 값을 가진다.
이진 탐색 트리의 장점과 용도
- 데이터 검색(탐색)에서 굉장히 많이 쓰인다.
- 장점은 탐색 속도를 개선할 수 있다는 점이다.
배열과 비교
구현
1. 노드 클래스 생성
1 |
|
2. 데이터 추가
1 |
|
3. 데이터 탐색
1 |
|
4. 데이터 삭제
- 매우 복잡하여 경우를 나눠 이해할 것이다.
4.1. 리프노드 삭제
- 삭제할 노드의 부모 노드가 삭제할 노드를 가리키지 않도록 한다.
4.2. 자식노드 하나인 노드 삭제
- 삭제할 노드의 부모 노드가 삭제할 노드의 자식 노드를 가리키도록 한다.
4.3. 자식노드 둘인 노드 삭제
- 삭제할 노드의 오른쪽 자식 중, 가장 작은 값을 삭제할 노드의 부모 노드가 가리키도록 한다.
- 삭제할 노드의 왼쪽 자식 중, 가장 큰 값을 삭제할 노드의 부모 노드가 가리키도록 한다.
4.3.1. 삭제할 노드의 오른쪽 자식 중, 가장 작은 값을 삭제할 노드의 부모 노드가 가리키도록 할 경우
- 삭제할 노드의 오른쪽 자식을 선택한다.
- 오른쪽 자식의 가장 왼쪽에 있는 노드를 선택한다.
- 해당 노드를 삭제할 노드의 부모 노드의 왼쪽 브랜치가 가리키게 한다.
- 해당 노드의 왼쪽 브랜치가 삭제할 노드 왼쪽 자식 노드를 가리키게 한다.
- 해당 노드의 오른쪽 브랜치가 삭제할 노드 오른쪽 자식 노드를 카리키게 한다.
- 만약 해당 노드가 오른쪽 자식 노드를 갖고 있을 경우, 해당 노드의 본래 부모 노드의 왼쪽 브랜치가 해당 오른쪽 자식 노드를 가리키게 한다.
삭제할 수 있는 코드를 짜고, 전체 코드를 짜보자.
시간 복잡도와 단점
시간 복잡도
- 깊이를 h라고 표기한다면 $O(h)$가 걸린다.
- $n$개의 노드를 가진다면, $h=log_2{n}$에 가까우므로, 시간복잡도는 $O(log{n})$이다.
단점
- 평균 시간 복잡도는 $O(log{n})$이지만, 이는 트리가 균형잡혀 있을 때의 평균 시간 복잡도이며, 위 이미지와 같이 구성되어있을 경우, 최악의 경우는 연결 리스트와 동일한 성능($O(n)$)을 보여준다.