CS/Data Structure
[ DS ] 트리 & 이진트리
KimBangg
2021. 8. 10. 20:01
1. 트리(Tree)란?
- 이전에 다뤄왔던 것들과는 다르게 "비선형" 구조인 계층 구졸르 가진 자료구조입니다.
- 여러 데이터가 계층 구조 안에서 서로 연결된 형태를 나타날 때 사용됩니다.
2. 용어정리(트리)
- 루트(Root) : 가장 상위에 있는 노드를 뜻합니다.
- 노드(Node) ; 트리 안에 들어있는 각 항목을 말합니다.
- 리프(Leaf) : 자식이 없는 가장 끝에 있는 노드를 의미합니다.
3. 트리의 특징
- left = index * 2
- right = index * 2 + 1
- parent = floor(index / 2)
4. 트리의 종류
- 이진트리
정점이 최대 2개의 자식을 가지는 트리를 의미한다.
- 완전 이진트리
리프 노드를 제외하고 모든 정점이 채워져있다.
- 포화 이진트리
완전 이진트리 + 마지막도 채워져있다면, 포화 이진 트리라고 한다.
- 이진트리의 특징
- N개의 정점을 가진 편향 트리가 될 수 있다.
- 정점이 N개인 포화 또는 완전 이진 트리의 높이는 로그 N이다.
- 높이가 h인 포화 이진 트리는 2^h -1 개의 정점을 가진다.
- 이진 탐색 트리와 다르게 좌/우에 따른 값의 차이는 없다.
5. 기본 트리 구현
class Node {
constructor(value) {
this.value = value;
this.children = [];
}
add(data) {
this.children.push(new Node(data));
}
remove(data) {
this.children = this.children.filter((child) =>
child.data === data ? false : true
);
}
}
class Tree {
constructor() {
this.root = null;
}
}
const t = new Tree();
t.root = new Node("a");
t.root.add("b");
t.root.add("c");
t.root.children[0].add("d");
\
6. 트리의 순회 [ 전위, 중위, 후위 ]
class Tree {
constructor(val) {
this.val = val;
this.leftNode = null;
this.rightNode = null;
}
setLeftNode(node) {
this.leftNode = node;
}
setRightNode(node) {
this.rightNode = node;
}
// 중위순회 [ left -> root -> right]
inOrderTree(node) {
if (!node) {
return;
}
return [
...this.inOrderTree(node.leftNode),
node.val,
...this.inOrderTree(node.rightNode),
];
}
// 전위순회 [ root -> left -> right]
preOrderTree(node) {
if (!node) {
return;
}
return [
node.val,
...this.inOrderTree(node.leftNode),
...this.inOrderTree(node.rightNode),
];
}
// 후위순회 [ left -> right -> root ]
postOrderTree(node) {
if (!node) {
return;
}
return [
...this.inOrderTree(node.leftNode),
...this.inOrderTree(node.rightNode),
node.val,
];
}
}
const root = new Tree("A");
let node = new Tree("B");
root.setLeftNode(node);
node = new Tree("C");
root.setRightNode(node);
node = new Tree("D");
root.leftNode.setLeftNode(node);
node = new Tree("E");
root.leftNode.setRightNode(node);
node = new Tree("F");
root.rightNode.setLeftNode(node);
node = new Tree("G");
root.rightNode.setRightNode(node);
// 중위 순회 left -> root -> right
root.inOrderTree(root);
console.log();
// 전위 순회 root -> left sub -> right sub
root.preOrderTree(root);
console.log();
// 후위 순회 왼쪽 -> 오른쪽 -> root
root.postOrderTree(root);
7. 이진 탐색 트리 구현
- 특징
1) 왼쪽 자식은 부모보다 작은 값을 가지고 있습니다.
2) 오른쪽 자식은 부모보다 큰 값을 가지고 있습니다.
- 부작용
작은 값 또는 큰 값만 들어오는 경우 한 쪽으로 치우친 트리가 나올수 있습니다.
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this.root = null;
}
insert(value) {
const newNode = new Node(value);
if ( this.root === null ) {
this.root = newNode;
return;
}
let currentNode = this.root;
while ( currentNode !== null ) {
if ( currentNode.value > value ) {
if ( currentNode.left === null ) {
currentNode.left = newNode;
break;
}
currentNode = currentNode.left;
} else {
if ( currentNode.right === null ) {
currentNode.right = newNode;
break;
}
currentNode = currentNode.right;
}
}
}
has(value) {
let currentNode = this.root;
while ( currentNode !== null ) {
if ( currentNode.value === value ) {
return true;
}
if ( currentNode.value < value ) {
currentNode = currentNode.right;
} else{
currentNode = currentNode.left;
}
}
return false;
}
}