node
- 트리를 구성하는 각 데이터 원소들
root
- 트리에서 부모가 없는 최상위 노드
- 트리의 시작점
- 최대 한개의 root 노드를 가질 수 있음
edge
- 각 노드를 연결하는 노드 간 선
트리는 root로 부터 구성되어 있고 edge로 연결되어 있다
parent child (sibling)
- 트리의 계층적 속성에서 상위에 위치한 노드를 parent 노드, 하위에 위치한 노드를 child 노드, 같은 부모를 가진 노드는 형제노드 라고 부른다
- parent 노드와 child 노드는 상대적인 개념이다
- 즉 누군가의 parent 노드가 될 수 있고 child 노드가 될 수 있음
degree
- 각 노드의 자식수를 나타냄
leaf
- 자식이 없는 노드를 나타냄
- 데이터의 끝 부분을 나타내기 때문에 terminal 노드 라고도 함
depth
- 각 노드에서 root까지의 거리를 depth라고 함
- 가장 큰 depth는 트리의 높이라고 함 === I, J, K
level
- 같은 depth를 가진 노드의 집합을 level이라고 함
path
- path를 표현할 때 중복노드를 포함하지 않음
- ex) A 부터 F 까지 경로를 표현할 때
= A → C → G → K (O)
= A → C → H → C → G → K (X)
- 전위탐색 preorder 정답
- A - B - D - H - E - C - F - I - J - G - K
- 중위탐색 inorder 정답
- D - H - B - E - A - I - F - J - C - G - K
- 후위탐색 postorder 정답
- H - D - E - B - I - J - F - K - G - C - A
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BinaryTree {
constructor() {
this.init();
}
init() {
this.root = null;
}
// 노드를 트리에 삽입하는 메서드
insert(value) {
const newNode = new Node(value);
if (this.root === null) this.root = newNode;
else this._insertRecursive(this.root, newNode);
}
// 노드를 재귀적으로 삽입할 수 있게 도와주는 메서드
_insertRecursive(currentNode, newNode) {
if (newNode.value < currentNode.value) {
if (currentNode.left === null) currentNode.left = newNode;
else this._insertRecursive(currentNode.left, newNode);
} else {
if (currentNode.right === null) currentNode.right = newNode;
else this._insertRecursive(currentNode.right, newNode);
}
}
// 전위 순회 메서드 (루트-왼쪽-오른쪽 순서)
preorderTraversal() {
const result = [];
this._preorderRecursive(this.root, result);
return result;
}
// 전위 순회를 재귀적으로 할 수 있게 도와주는 메서드
_preorderRecursive(currentNode, result) {
if (currentNode !== null) {
result.push(currentNode.value);
this._preorderRecursive(currentNode.left, result);
this._preorderRecursive(currentNode.right, result);
}
}
// 중위 순회 메서드 (왼쪽-루트-오른쪽 순서)
inorderTraversal() {
const result = [];
this._inorderRecursive(this.root, result);
return result;
}
// 중위 순회를 재귀적으로 할 수 있게 도와주는 메서드
_inorderRecursive(currentNode, result) {
if (currentNode !== null) {
this._inorderRecursive(currentNode.left, result);
result.push(currentNode.value);
this._inorderRecursive(currentNode.right, result);
}
}
// 후위 순회 메서드 (왼쪽-오른쪽-루트 순서)
postorderTraversal() {
const result = [];
this._postorderRecursive(this.root, result);
return result;
}
// 후위 순회를 재귀적으로 할 수 있게 도와주는 메서드
_postorderRecursive(currentNode, result) {
if (currentNode !== null) {
this._postorderRecursive(currentNode.left, result);
this._postorderRecursive(currentNode.right, result);
result.push(currentNode.value);
}
}
}
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.init();
}
init() {
this.root = null;
}
// 노드를 트리에 삽입하는 메서드
insert(value) {
const newNode = new Node(value);
if (this.root === null) this.root = newNode;
else this._insertRecursive(this.root, newNode);
}
// 노드를 재귀적으로 삽입할 수 있게 도와주는 메서드
_insertRecursive(currentNode, newNode) {
if (newNode.value < currentNode.value) {
if (currentNode.left === null) currentNode.left = newNode;
else this._insertRecursive(currentNode.left, newNode);
} else {
if (currentNode.right === null) currentNode.right = newNode;
else this._insertRecursive(currentNode.right, newNode);
}
}
// 트리에서 노드를 삭제하는 메서드
delete(value) {
this.root = this._deleteRecursive(this.root, value);
}
// 노드를 재귀적으로 삭제할 수 있게 도와주는 메서드
_deleteRecursive(currentNode, value) {
if (currentNode === null) return null;
if (value < currentNode.value)
currentNode.left = this._deleteRecursive(currentNode.left, value);
else if (value > currentNode.value)
currentNode.right = this._deleteRecursive(currentNode.right, value);
else {
// 삭제할 노드를 찾았을 때
if (currentNode.left === null) return currentNode.right;
else if (currentNode.right === null) return currentNode.left;
// 두 자식이 있는 경우, 오른쪽 서브트리에서 최소값을 찾아 대체
currentNode.value = this._findMinValue(currentNode.right);
currentNode.right = this._deleteRecursive(
currentNode.right,
currentNode.value,
);
}
return currentNode;
}
// 오른쪽 서브트리에서 최소값을 찾는 메서드
_findMinValue(node) {
let current = node;
while (current.left !== null) {
current = current.left;
}
return current.value;
}
// 트리에서 특정 값을 검색하는 메서드
search(value) {
return this._searchRecursive(this.root, value);
}
// 값을 재귀적으로 검색할 수 있게 도와주는 메서드
_searchRecursive(currentNode, value) {
if (currentNode === null) return false;
if (value === currentNode.value) return true;
else if (value < currentNode.value)
return this._searchRecursive(currentNode.left, value);
// 왼쪽 서브트리 탐색
else return this._searchRecursive(currentNode.right, value); // 오른쪽 서브트리 탐색
}
}