현재 노드를 기준으로 왼쪽에는 작은 값, 오른쪽은 큰 값으로 정렬해 놓는 이진 트리 기반 자료 구조
_insertNode (node, value) {
if (node === null) {
node = new Node(value);
} else if (value < node.value) {
node.left = this._insertNode(node.left, value);
} else if (value > node.value) {
node.right = this._insertNode(node.right, value);
}
return node;
}
insert (value) {
this.root = this._insertNode(this.root, value);
}
_inOrderTraverseNode (node, callback) {
if (node === null) return;
this._inOrderTraverseNode(node.left, callback);
callback(node);
this._inOrderTraverseNode(node.right, callback);
}
inOrderTraverse (callback) {
this._inOrderTraverseNode(this.root, callback);
console.log("end");
}
1) 가장 최대값의 경우, 가장 오른쪽에 위치한 노드이다.
2) node.right가 null이 아닐 때까지 이동해서 해당 node를 리턴한다.
_maxNode (node) {
if (node === null) return null;
while (node && node.right !== null) {
node = node.right;
}
return node.value;
}
max () {
return this._maxNode(this.root);
}
1) 최소값의 경우, 가장 왼쪽에 위치한 노드이다.
2) node.left가 null이 아닐 때까지 이동해서 해당 node를 리턴한다.
_minNode (node) {
if (node === null) return null;
while (node && node.left !== null) {
node = node.left;
}
return node.value;
}
min () {
return this._minNode(this.root);
}
1) _insertNode 메서드와 비슷하다.
2) node.value === value일 경우 바로 true를 리턴한다.
3) node.value < value일 경우, 다시 재귀를 통해 node.right에서 만족하는 노드를 찾는다.
4) node.value > value일 경우, 다시 재귀를 통해 node.left에서 만족하는 노드를 찾는다.
_searchNode (node, value) {
if (node === null) return false;
if (node.value === value) {
return true;
} else if (value < node.value) {
return this._searchNode(node.left, value);
} else if (value > node.value) {
return this._searchNode(node.right, value);
}
}
search (value) {
return this._searchNode(this.root, value);
}
child node가 하나도 없을 때, 바로 해당 노드를 null로 만든다.
child node가 1개일 때
node의 오른쪽이 없을 경우, node = node.left가 되고
node의 왼쪽이 없을 경우, node = node.right가 된다.
child node가 2개일 때
내가 삭제할 노드 찾기 → 바로 삭제를 할 수 있는가? (연결 고리) → 삭제한 노드를 this.root에 연결
_removeNode (node, value) {
if (node.value === value) {
// case 1: 0 child node
if (node.left === null && node.right === null) {
node = null;
}
// case 2: 1 child node
else if (node.left === null) {
node = node.right;
} else if (node.right === null) {
node = node.left;
}
// case 3: 2child node
else {
let temp = this._findMinNode(node.right);
node.value = temp.value;
node.right = this._removeNode(node.right, temp.value);
}
} else if (node.value < value) {
node.right = this._removeNode(node.right, value);
} else if (node.value > value) {
node.left = this._removeNode(node.left, value);
}
return node;
}
remove (value) {
this.root = this._removeNode(this.root, value);
}
관련 전체 코드는 Git에 업로드 해두었습니다.
Github_BinarySearchTree