본 장 이해 후, 다음 프로젝트를 해보세요: https://drive.google.com/drive/folders/1ljJLJQsosmDDH6RY3_tesgMM-WRlnw9S?usp=sharing
일반적인 트리 자료 구조는 자식 노드를 지닌 노드들로 구성된다. 즉 계층형 데이터 관리 구조이다. 첫 번째이자 가장 상위 노드를 루트 노드(root node)라고 한다. 한 노드의 하위에있는 노드를 child node라고하고, child node의 상위 노드를 parent node라고 한다. 트리형 자료구조의 가장 대표적인 것이 이진탐색트리이다. 이번 시간에 이진탐색 트리를 알아보고, 구현하보도록 하겠습니다.
트리의 속성 중 가장 중요한 것이 '루트노드'를 제외한 모든 노드는 단 하나의 부모노드를 갖는다는 특징이 있다. 이 속성에서 파생적으로 나오는 특징이 있는데
각 부모에 연결된 노드의 수가 최대 2개인 트리를 이진트리라고 한다. 이러한 이진트리에 조건이 투가된 것이 이진탐색트리이다. 이진 트리는 많은 양의 노드를 낮은 높이에서 관리할 수 있다는 점에서 데이터 효율성이 높아진다. 데이터 저장 및 탐색 등의 다양한 목적으로 사용할 수 있다.
이진탐색트리는 이진탐색과 링크드 리스트를 결합한 자료구조의 일종이다. 효율적인 탐색 능력을 유지하면서, 자료 입력과 삭제를 가능하게 만들어졌다.
이진탬색트리의 기본적인 모습은 하나의 노드에 두개의 자식이 있다. 왼쪽 자식의 경우 부모보다 작은 수, 오른쪽 자식의 경우 부모보다 큰 수가 들어간다. 또한 중복된 노드가 없어야하고, 작게보면 각각 노드들 자체도 모두 이진트리의 모습을 하고 있다.
class BST {
constructor(value) {
this.value = value;
this.right = null;
this.left = null;
}
insert(value) {
if (value <= this.value) {
if (!this.left) {
this.left = new BST(value);
} else {
this.left.insert(value);
}
} else if (value > this.value) {
if (!this.right) {
this.right = new BST(value);
} else {
this.right.insert(value);
}
}
}
contains(value) {
if (value === this.value) {
return true
} else if (value < this.value) {
if (!this.left) {
return false;
} else {
return this.left.contains(value);
}
} else if (value > this.value) {
if (!this.right) {
return false;
} else {
return this.right.contains(value);
}
}
}
depthFirstTraversal(iterator, order) {
if (order === 'pre-order') {
iterator(this.value);
}
if (this.left) {
this.left.depthFirstTraversal(iterator, order);
}
if (order === 'in-order') {
iterator(this.value);
}
if (this.right) {
this.right.depthFirstTraversal(iterator, order);
}
if (order === 'post-order') {
iterator(this.value);
}
}
breadthFirstTraversal(iterator) {
const queue = [this];
while (queue.length) {
let treeNode = queue.shift();
iterator(treeNode);
if (treeNode.left) {
queue.push(treeNode.left);
}
if (treeNode.right) {
queue.push(treeNode.right);
}
}
}
getMinimun() {
if (this.left) {
return this.left.getMinimun();
} else {
return this.value;
}
}
getMaximum() {
if (this.right) {
return this.right.getMaximum();
} else {
return this.value;
}
}
}
const bst = new BST(1);
bst.left = new BST(2);
bst.right = new BST(3);
bst.left.left = new BST(4);
bst.left.right = new BST(5);
// console.log(bst);
bst.depthFirstTraversal(console.log, 'post-order');