부모와 자식간의 관계로 구성되어 있다.
리스트는 선형구조 ( 한줄로 있는 구조 )
트리는 비선형 구조 ( 한 갈래에서 여러가지 가지로 뻗어나갈 수 있다 )
트리는 부모-자식 관계에 따라서 자식 노드만 가리킬 수 있다.
자식이 부모를 가리키거나 형제를 가리킬 수 없다 >> 이것은 그래프다.
일반적인 트리는 자식이 몇개 있던 상관없지만 이진트리의 경우는 각 노드가 최대 두개의 자식을 가져야한다.
작은 것들은 왼쪽, 큰 것들은 오른쪽에 놓는 방식이 어떠한 값을 찾는데에 빠르게 동작한다.
정렬되지 않은 트리와 비교했을 때는 어떠한 값을 찾는다면 이진탐색트리가 더 유리하다.
일반트리에서는 모든 값들을 순회해야하지마 BST에서는 비교할 때마다 탐색해아하는 횟수나 노드의 숫자가 줄어든다 .
class BinarySearchTree{
constructor(){
this.root = null;
}
}
class Node{
constructor(value){
this.value = value;
this.left = null;
this.right= null;
}
}
let tree= new BinarySearchTree();
tree.root = new Node(10);
tree.root.right = new Node(15);
tree.root.left = new Node(7);
tree.root.left.right = new Node(9);
의사코드
코드
insert(value){
let newNode = new Node(value);
if(!this.root){
this.root = newNode;
return this
}
let curNode = this.root;
let count=0;
while(curNode){
if(value === curNode.value) return undefiend;
if(value < curNode.value) {
if(curNode.left === null) {
curNode.left = newNode;
return this;
}
curNode = curNode.left
}
else {
if(curNode.right === null) {
curNode.right = newNode;
return this;
}
curNode = curNode.right
}
}
return this;
}
find(value){
if(!this.root) return false;
let curNode = this.root;
while(curNode){
if(curNode.value===value) return true;
if(value<curNode.value) curNode= curNode.left;
else curNode = curNode.right;
}
return false
}
현재 노드 기준으로 검사하였다.
트리가 위의 그림에 비해서는 노드의 개수가 2배가 추가되었지만
이진탐색트리는 데이터가 이미 정렬이 되어있기 때문에 한단계만 더 확인하면 된다.
삽입 - O(log N)
탐색 - O(log N)
한쪽으로 치우친 트리의 경우 시간복잡도가 달라질 수 있다.
이럴 경우는 삽입이나 탐색을 할 때 노드의 숫자만큼 단계가 추가되기 때문에 시간복잡도가 O(lon N)에 해당하지 않는다.
만약에 이것을 꼭 트리로 사용해야 한다면, 다른 숫자를 루트로 놓고 이진탐색트리를 다시 작성하는 것이 좋다.