Data Structures & Algorithms with Javascript : Sets
[์ด์ ๊ธ]2024.07.23 - [๐ค data structures & algorithms] - Data Structures & Algorithms with Javascript : Hashing Data Structures & Algorithms with Javascript : Hashing[์ด์ ๊ธ] 2024.07.22 - [๐ค data structures & algorithms] - Data Structures & A
pyotato-dev.tistory.com
๐ฒ ํธ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ธต์ ์ผ๋ก ๋ํ๋ผ ๋ ์ ์ฉํ ๋น์ ํ ์๋ฃ ๊ตฌ์กฐ๋ค.
ํธ๋ฆฌ ์๋ฃ ๊ตฌ์กฐ๋ฅผ ํ์ผ ์์คํ ์ด๋ ๋ฐ์ดํฐ ๋ฆฌ์คํธ๋ฅผ ์ ๋ ฌํ๋๋ฐ ์ข ์ข ์ฐ๊ณค ํ๋ค.
์ค๋์ ํธ๋ฆฌ ๊ตฌ์กฐ ์ค "์ด์ง ํธ๋ฆฌ (binary tree)"์ ๋ํด ์ดํด๋ณด์.
์ด์ง ํธ๋ฆฌ๋ linked list ๋ณด๋ค ๊ฒ์์ด ๋น ๋ฅด๊ณ , array๋ณด๋ค ๋ฐ์ดํฐ ์ฝ์ /์ญ์ ๊ฐ ๋น ๋ฅด๊ธฐ ๋๋ฌธ์ ๋ ์ ํธ๋๋๋ฐ,
๐ฉ๐ป๐ป ์ด์ง ํธ๋ฆฌ๊ฐ ๋ฌด์์ธ์ง ์์๋ณด๊ณ , ์๋ฐ์คํฌ๋ฆฝํธ class๋ก ์๋ฃ ๊ตฌ์กฐ์ ์ฐ์ฐ๋ค์ ๊ตฌํํด๋ณด์.
๐ฒ ํธ๋ฆฌ ์๋ฃ ๊ตฌ์กฐ๋?
ํธ๋ฆฌ ์๋ฃ ๊ตฌ์กฐ๋ node์ edge๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์๋ฅผ ๋ค์ด ๋ค์ ๊ทธ๋ฆผ์ ์กฐ์ง ๊ด๊ณ๋๋ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋์ด ์๋ค.
๊ฐ ์งํจ์ node๋ฅผ ๋ํ๋ด๊ณ , ๊ฐ ์งํจ์ ๊ด๊ณ๊ฐ edge์ ํด๋น๋๋ค.
CIO๋ CEO์ ์ง์ ๋ณด๊ณ ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ edge๋ก ์ฐ๊ฒฐ๋์ด ์๊ณ , VP์ CEO๋ํ ๊ฐ์ ๊ด๊ณ์ด๋ฏ๋ก edge๋ก ์ฐ๊ฒฐ๋์ด ์๋ค.
ํ์ง๋ง VP sales์ development manager๋ ์๋ก ๋ณด๊ณ ๋ฅผ ์ง์ ์ฃผ๊ณ ๋ฐ๋ ์ฌ์ด๊ฐ ์๋๊ธฐ ๋๋ฌด๋ค edge๋ก ์ฐ๊ฒฐ๋์ด ์์ง ์๊ณ , ์ง์ ๊ด๋ จ์ด ์๋ ๋ถ์๊ฐ ์๋๋ผ๊ณ ๋ณผ ์ ์๋ค.
ํธ๋ฆฌ์ ๊ตฌ์ฑ์์๋ฅผ ๋ ์์ธํ ์ดํด๋ณด๊ธฐ ์ํด ๋ค์์ ํธ๋ฆฌ๋ฅผ ์ดํด๋ณด์.
ํธ๋ฆฌ๋ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ง๋ ๋ฐ์ดํฐ๋ผ๊ณ ์์ ์ด์ผ๊ธฐํ๋ค. ์์ ๊ทธ๋ฆผ์ฒ๋ฌ level๋ก ๊ฐ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ํ๋ผ ์ ์๋ค.
๋ ๋ฒจ 0์ธ ์ต์์ ๋ ธ๋๋ root๋ผ๊ณ ๋ ๋ถ๋ฆฐ๋ค. ๋ฃจํธ ๋ ธ๋ ์๋์ ๋ ธ๋๋ค์ด ์๋๋ฐ, ์ด ๋ ธ๋๋ค์ child (์์) ๋ ธ๋๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๊ทธ๋ฆฌ๊ณ child ๋ ธ๋ ์์์ ๋ ธ๋๋ฅผ parent (๋ถ๋ชจ) ๋ ธ๋๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์์ ๋ ธ๋๊ฐ ์๋ ๋ ธ๋๋ leaf ๋ ธ๋๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์ค๋์ ํธ๋ฆฌ ์ค์์๋ binary tree (์ด์ง ํธ๋ฆฌ)์ ๋ํด์ ์ดํด๋ณผ ๊ฑด๋ฐ, ์ด์ง ํธ๋ฆฌ๋ ๋ชจ๋ ๋ ธ๋์ ์์ ๋ ธ๋ ๊ฐ์๊ฐ 2๊ฐ ์ดํ์ธ ํธ๋ฆฌ๋ฅผ ์ผ์ปซ๋๋ค. ๊ฐ ๋ ธ๋๋ key๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ ๊ฐ์ ์ง๋๊ณ ์๋ค. ํ๋์ ๋ ธ๋ A๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ์ ์๋ ๊ฐ์ left child of A๋ผ๊ณ ํํํ๊ณ , ์ค๋ฅธ์ชฝ์ ์๋ ์์ ๋ ธ๋๋ฅผ right child of A๋ผ๊ณ ํ๋ค.
๊ฐ ๋ ธ๋์ ์ง์ ์ฐ๊ฒฐ๋ ๊ด๊ณ๋ฅผ edge๋ผ๊ณ ํ์๋๋ฐ, ํ๋์ ๋ ธ๋์์ ๋ค๋ฅธ ๋ ธ๋๋ก ์ ๊ทผํ๊ธฐ ์ํ ์ผ๋ จ์ edge๋ค์ path๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ชจ๋ ๋ ธ๋๋ฅผ ํน์ ์์์ ๋ฐ๋ผ ๋ฐฉ๋ฌธํ๋ ๊ณผ์ ์ tree traversal(ํธ๋ฆฌ ์ํ)๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๐ฒ Binary Tree(์ด์งํธ๋ฆฌ)์ Binary Search Tree(์ด์ง ํ์ ํธ๋ฆฌ)
์ด์ง ํธ๋ฆฌ๋ ์์ ๋ ธ๋์ ๊ฐ์๊ฐ 2๊ฐ ์ดํ๋ก ์ ํ๋ ํธ๋ฆฌ ๊ตฌ์กฐ๋ผ๋ ๊ฒ์ ์ดํด๋ดค๋ค.
์์ ๋ ธ๋์ ๊ฐ์๋ฅผ ์ต๋ 2๊ฐ๋ก ์ ํํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ฝ์ , ์ญ์ ๊ทธ๋ฆฌ๊ณ ๊ฒ์ํ๋ ๊ณผ์ ์ด ํจ์จ์ ์ด๋ค.
์๋ํ๋ฉด ๊ฐ์ ์ผ์ชฝ ๋๋ ์ค๋ฅธ์ชฝ ๋ ธ๋๋ก๋ง ์ ์ฅํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์ง ํ์ ํธ๋ฆฌ๋ ์์ ๋ ธ๋๋ฅผ ๋ ์์ธํ ๋ถ๋ฅ ๊ธฐ์ค์ผ๋ก ์ ์ฅํ ์ด์ง ํธ๋ฆฌ๋ค.
์ด์ง ํ์ ํธ๋ฆฌ๋ 2๊ฐ ์ดํ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ๋ ๊ฒ๊ณผ ํจ๊ป, ํญ์ ์์ ํค ๊ฐ์ด ์ผ์ชฝ์ ์๊ณ , ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ์๋ก ํฐ ๊ฐ์ผ๋ก ์ด๋ฃจ์ด์ง๋ค.
๐ ์ด์ง ํ์ ํธ๋ฆฌ(BST) ๊ตฌํ
์ด์ง ํ์ ํธ๋ฆฌ๋ ๋
ธ๋๋ก ๊ตฌ์ฑ๋๋ค. ๋จผ์ ๋
ธ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด ๋ณด์. ๋
ธ๋ ํด๋์ค๋ linked list์ ์ ์ฌํ ๊ตฌ์กฐ๋ค.
โผ ์์ ๋ ์ฑ ์ ๊ตฌํ์ ์ฐธ๊ณ ํ์ฌ ํด๋์ค๋ก ์ฌ๊ตฌ์ฑํ์ต๋๋ค!!
Node ํด๋์ค๋ ์ผ์ชฝ ์ค๋ฅธ์ชฝ์ ์ ์ฅํ ๋ ธ๋ ์ฐธ์กฐ์ ํ์ฌ ๋ ธ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ค show ๋ฉ์๋๋ก ๊ตฌ์ฑ๋๋ค.
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
}
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return this.data;
}
}
BST ํด๋์ค๋ ๋ฃจํธ ๋ ธ๋ ๋ฉค๋ฒ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ ๋ฉ์๋์ธ insert๋ก ๊ตฌ์ฑ๋๋ค.
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
}
๐ BST ์ํ
BST์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ ์ฐ์ฐ๊น์ง ์ดํด๋ดค๋ค. ํธ๋ฆฌ๊ฐ ๊ณ์ธต ๊ตฌ์กฐ๋ผ๋ ์ ์ ์ด๋ ค์ ๋ฐ์ดํฐ๋ฅผ ๋ณผ ์ ์์ผ๋ฉด ์ข์ ๊ฑฐ ๊ฐ๋ค.
BST๋ฅผ ์ํํ๋ ๋ฐฉ์์๋ 3๊ฐ์ง๊ฐ ์๋ค:
Inorder : ๋ชจ๋ ๋ ธ๋์ ํค๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ๋ฐฉ๋ฌธ
Preorder : ๋ฃจํธ ๋จผ์ ๋ฐฉ๋ฌธ => ๋ฃจํธ ๋ ธ๋ ์ผ์ชฝ subtree ์์ ๋ ธ๋๋ค => ๋ฃจํธ ๋ ธ๋ ์ค๋ฅธ์ชฝ subtree ์์ ๋ ธ๋๋ค ๋ฐฉ๋ฌธ
Postorder : ์ผ์ชฝ ๋ฆฌํ ๋ฐฉ๋ฌธ =>ํด๋น subtree ์์ ๋ ธ๋ ๋ฐฉ๋ฌธ => ์ค๋ฅธ์ชฝ subtree ์์ ๋ ธ๋ ๋ฐฉ๋ฌธ => ๋ฃจํธ ๋งจ ๋ง์ง๋ง์ ๋ฐฉ๋ฌธ
๐ฉ๐ป๐ป BST ์ํ ๊ตฌํ
์ํ ์ฝ๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ๊ทํจ์๋ฅผ ๋ฐํ์ผ๋ก ํ๋ค.
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
์ ์ฒด ์ฝ๋
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
}
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return this.data;
}
}
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
}
// ์ถ๋ ฅ ์ ํธ ํจ์
function print(item){
console.log(item);
}
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
let nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
print("Inorder traversal:");
inOrder(nums.root);
print("Preorder traversal:");
preOrder(nums.root);
print("Postorder traversal:");
postOrder(nums.root);
์ํ ๊ฒฐ๊ณผ ์ดํด๋ณด๊ธฐ
/**
Inorder traversal:
3
16
22
23
37
45
99
Preorder traversal:
23
16
3
22
45
37
99
Postorder traversal:
3
22
16
37
99
45
23
*/
ํธ๋ฆฌ ๋ ธ๋ ์ถ๊ฐ ๊ณผ์
let nums = new BST();
nums.insert(23); -----> root [23]
\
nums.insert(45); [45]
nums.insert(16); root [23]
/ \
[16] [45]
/
nums.insert(37); [37]
nums.insert(3); root [23]
/ \
[16] [45]
/ /
[3] [37]
nums.insert(99); root [23]
/ \
[16] [45]
/ / \
[3] [37] [99]
nums.insert(22); root [23]
/ \
[16] [45]
/ \ / \
[3] [22] [37] [99]
ํธ๋ฆฌ ์ํ ๊ณผ์
root [23]
a / \ b
[16] [45]
c / \ d e / \ f
[3] [22] [37] [99]
Inorder traversal:
path : c => d => a => e => f
๋ ธ๋ ๋ฐฉ๋ฌธ : [3] [16] [22] [23] [37] [45] [99]
Preorder traversal:
path : a => c => d => e => f
๋ ธ๋ ๋ฐฉ๋ฌธ : [23] [16] [3] [22] [45] [37] [99]
Postorder traversal:
path : c => d => e => f => a
๋ ธ๋ ๋ฐฉ๋ฌธ : [3] [22] [16] [37] [99] [45] [23]
inorder, preorder, postorder ์ํ ๋น๊ต
๐ BST ํ์
bst ํ์์ ์ฃผ๋ก ํ์ฉ๋๋ ์๋ ํฌ๊ฒ ๋ค์ 3๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์๋ค
- ํน์ ๊ฐ ์ฐพ๊ธฐ
- ์ต์ ๊ฐ ์ฐพ๊ธฐ
- ์ต๋ ๊ฐ ์ฐพ๊ธฐ
์ต๋/์ต์ ๊ฐ ์ฐพ๊ธฐ
BST์์ ์ต๋/์ต์๊ฐ์ ๋น๊ต์ ๊ฐ๋จํ ๋ฐฉ์์ผ๋ก ์ ์ฅ๋๋ค.
๊ฐ์ด ์์ ์๋ก ์ผ์ชฝ ์์ ๋ ธ๋์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ BSt์ ์ต์๊ฐ์ ์ฐพ๊ธฐ ์ํด์๋
BST์ ์ผ์ชฝ edge๋ฅผ ์ํํ๋ฉด์ ๋งจ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
์ต์ ๊ฐ์ ๊ตฌํ๊ธฐ ์ํ ๋ฉ์๋ getMin()๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํด๋ณผ ์ ์๋ค.
getMin(){
let current = this.root; // ๋ฃจํธ ๋
ธ๋๋ก๋ถํฐ ์์ํด์
while(!(current.left == null)){ // ๋ ์ด์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์์ ๋๊น์ง ๊ฒ์
current = current.left;
}
return current.data; // ๋งจ ์ผ์ชฝ์ leaf ๋
ธ๋๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ด๋ฏ๋ก ๋ฆฌํด
}
์ต๋ ๊ฐ์ ๋ฐ๋๋ก ๊ฐ์ฅ ์ค๋ฅธ์ชฝ์ leaf ๋ ธ๋๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
getMax(){
let current = this.root;
while(!(current.right == null)){
current = current.right;
}
return current.data;
}
๐ ์ ์ฒด ์ฝ๋!
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
}
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return this.data;
}
}
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
getMin(){
let current = this.root; // ๋ฃจํธ ๋
ธ๋๋ก๋ถํฐ ์์ํด์
while(!(current.left == null)){ // ๋ ์ด์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์์ ๋๊น์ง ๊ฒ์
current = current.left;
}
return current.data; // ๋งจ ์ผ์ชฝ์ leaf ๋
ธ๋๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ด๋ฏ๋ก ๋ฆฌํด
}
getMax(){
let current = this.root;
while(!(current.right == null)){
current = current.right;
}
return current.data;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
}
// ์ถ๋ ฅ ์ ํธ ํจ์
function print(item){
console.log(item);
}
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
let nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
let min = nums.getMin();
let max = nums.getMax();
print(`bst nums์ ์ต์๊ฐ: ${min}, ์ต๋๊ฐ: ${max}`);
// bst nums์ ์ต์๊ฐ: 3, ์ต๋๊ฐ: 99
ํน์ ๊ฐ ์ฐพ๊ธฐ
bst์์ ํน์ ๊ฐ์ ์ฐพ๊ธฐ ์ํด์๋ ํ์ฌ ๋ ธ๋์ ์ฐพ์ผ๋ ค๋ ๊ฐ ๊ฐ์ ๋์ ๋น๊ต๊ฐ ํ์ํ๋ค.
๋์ ๋น๊ต๋ฅผ ํตํด ์ฐพ์ผ๋ ค๋ ๊ฐ์ด ํ์ฌ ๋ ธ๋๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ ๋ ธ๋๋ก ์ด๋ํ๊ณ ,
์ฐพ์ผ๋ ค๋ ๊ฐ์ด ์๋ค๋ฉด ํ์ฌ ๋ ธ๋ ๊ธฐ์ค ์ผ์ชฝ ๋ ธ๋๋ก ์ด๋ํด์ ์ฐพ์ผ๋ฉด ๋๋ค.
find() ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ํด๋์ค์ ์ถ๊ฐํด๋ณด์.
find(data){
let current = this.root;
while(current.data != data){
if(data < current.data){ // ์ฐพ์ผ๋ ค๋ ๊ฐ์ด ํ์ฌ ๋
ธ๋๋ณด๋ค ์๋ค๋ฉด
current = current.left; // ์ผ์ชฝ ์๋ธ ํธ๋ฆฌ๋ก ์ด๋ํด์ ๊ฒ์
} else {
current = current.right; // ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํด์ ๊ฒ์
}
if(current == null){
return null;
}
}
return current;
}
๐ ์ ์ฒด ์ฝ๋!
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
}
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return this.data;
}
}
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
getMin(){
let current = this.root; // ๋ฃจํธ ๋
ธ๋๋ก๋ถํฐ ์์ํด์
while(!(current.left == null)){ // ๋ ์ด์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์์ ๋๊น์ง ๊ฒ์
current = current.left;
}
return current.data; // ๋งจ ์ผ์ชฝ์ leaf ๋
ธ๋๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ด๋ฏ๋ก ๋ฆฌํด
}
getMax(){
let current = this.root;
while(!(current.right == null)){
current = current.right;
}
return current.data;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
find(data){
let current = this.root;
while(current.data != data){
if(data < current.data){ // ์ฐพ์ผ๋ ค๋ ๊ฐ์ด ํ์ฌ ๋
ธ๋๋ณด๋ค ์๋ค๋ฉด
current = current.left; // ์ผ์ชฝ ์๋ธ ํธ๋ฆฌ๋ก ์ด๋ํด์ ๊ฒ์
} else {
current = current.right; // ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํด์ ๊ฒ์
}
if(current == null){
return null;
}
}
return current;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
}
// ์ถ๋ ฅ ์ ํธ ํจ์
function print(item){
console.log(item);
}
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
let nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
let findValues = [3,12,25,23,33,45,99];
findValues.forEach((value)=>{
let hit = nums.find(value);
print(`value ${value} ${hit==null?"is not":""} in bst`);
})
/**
value 3 in bst
value 12 is not in bst
value 25 is not in bst
value 23 in bst
value 33 is not in bst
value 45 in bst
value 99 in bst
*/
BST์์ ๋ ธ๋ ์ ๊ฑฐ
BST ์ฐ์ฐ ์ค์์ ๊ฐ์ฅ ๋ณต์กํ ์ฐ์ฐ์ ๋ ธ๋๋ฅผ ์ ๊ฑฐํ๋ ๊ณผ์ ์ด๋ค. ๋ ธ๋ ์ ๊ฑฐ์ ๋ณต์ก๋๋ ์ด๋ค ๋ ธ๋๋ฅผ ์ ๊ฑฐํ๊ณ ์ถ๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค. leaf ๋ ธ๋๋ฅผ ์ ๊ฑฐํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์ ๊ฑฐ ์ฝ๋๋ฅผ ๋น๊ต์ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค.
ํ์ง๋ง ์์ ๋ ธ๋๊ฐ ํ๋ ์๋ค๋ฉด ์ข ๋ ๋ณต์กํด์ง๊ณ , ์์ ๋ ธ๋๊ฐ ๋์ด๋ผ๋ฉด ๋์ฑ ๋ ๋ณต์กํด์ง๋ค.
๋ ธ๋ ์ญ์ ์ ๋ณต์ก๋๋ฅผ ๋ฎ์ถ๊ธฐ ์ํด ๋ ธ๋๋ฅผ ์ฌ๊ท์ ์ผ๋ก ์ ๊ฑฐํ๋ ๊ณผ์ ์ผ๋ก ๊ฐ์ํํด๋ณด๊ณ ์ ํ๋ค.
๋ ธ๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ๋ฉ์๋๋ ๋๊ฐ์ง๋ค : remove()์ removeNode()
๊ตฌํ ๋ ผ๋ฆฌ
1. ํ์ฌ ๋ ธ๋๊ฐ ์ฐ๋ฆฌ๊ฐ ์ญ์ ํ๋ ค๋ ๋ ธ๋๋ฅผ ํฌํจํ๊ณ ์๋๊ฐ? => ํด๋น ๋ ธ๋ ์ญ์
2. ์๋๋ผ๋ฉด ํ์ฌ๋ ธ๋์ ์ฐ๋ฆฌ๊ฐ ์ญ์ ํ๋ ค๋ ๋ ธ๋ ๋น๊ต
2 - 1. ์ญ์ ํ๊ณ ์ํ๋ ๋ ธ๋๊ฐ ํ์ฌ ๋ ธ๋๋ณด๋ค ์๋ค๋ฉด ์ผ์ชฝ ์์ ๋ ธ๋๋ก ์ด๋ํด์ ๋น๊ต
2 - 2. ์ญ์ ํ๊ณ ์ํ๋ ๋ฐ์ดํฐ๊ฐ ํ์ฌ ๋ ธ๋๋ณด๋ค ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ก ์ด๋ํด์ ๋น๊ต
๊ณ ๋ ค์ฌํญ
1. ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋๊ฐ leaf์ธ ๊ฒฝ์ฐ => ํด๋น ๋ ธ๋์ parent node๊ฐ null์ ๊ฐ๋ฆฌํค๋๋ก
2. ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋๊ฐ ํ๋์ ์์ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ => ์์ ๋ ธ๋๊ฐ ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค๋๋ก
3. ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋๊ฐ ๋ ๊ฐ์ ์์ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ
3 - 1. ์ ๊ฑฐํ ๋ ธ๋์ ์ผ์ชฝ์์ subtree ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ ์ฐพ๊ฑฐ๋
3 - 2. ์ ๊ฑฐํ ๋ ธ๋์ ์ค๋ฅธ์ชฝ์์ subtree ์ค ๊ฐ์ฅ ์์ ๊ฐ์ ์ฐพ๊ธฐ ( โ๏ธ ์ ํ )
4. subtree์ ์ต์๊ฐ์ ๊ตฌํ๋ ํจ์ => ์์ ์ต์ ๊ฐ์ ์ง๋ ๋ ธ๋ ๊ตฌํด์ ํ์ฌ
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
}
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return this.data;
}
}
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
getMin(){
let current = this.root; // ๋ฃจํธ ๋
ธ๋๋ก๋ถํฐ ์์ํด์
while(!(current.left == null)){ // ๋ ์ด์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์์ ๋๊น์ง ๊ฒ์
current = current.left;
}
return current.data; // ๋งจ ์ผ์ชฝ์ leaf ๋
ธ๋๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ด๋ฏ๋ก ๋ฆฌํด
}
getMax(){
let current = this.root;
while(!(current.right == null)){
current = current.right;
}
return current.data;
}
find(data){
let current = this.root;
while(current.data != data){
if(data < current.data){ // ์ฐพ์ผ๋ ค๋ ๊ฐ์ด ํ์ฌ ๋
ธ๋๋ณด๋ค ์๋ค๋ฉด
current = current.left; // ์ผ์ชฝ ์๋ธ ํธ๋ฆฌ๋ก ์ด๋ํด์ ๊ฒ์
} else {
current = current.right; // ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํด์ ๊ฒ์
}
if(current == null){
return null;
}
}
return current;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
remove(data){
this.root = this.removeNode(this.root, data);
}
removeNode(node, data){
if(node == null){
return null;
}
if(data == node.data){
// ๋
ธ๋๊ฐ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.left == null && node.right == null){
return null;
}
// ๋
ธ๋๊ฐ ์ผ์ชฝ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.left == null){
return node.right;
}
// ๋
ธ๋๊ฐ ์ค๋ฅธ์ชฝ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.right == null){
return node.left;
}
// ๋
ธ๋๊ฐ ์์์ด ๋๊ฐ์ ๊ฒฝ์ฐ
let tempNode = this.getMin();
node.data = tempNode.data;
node.right = this.removeNode(node.right, tempNode.data);
return node;
}
else if(data< node.data){
node.left = this.removeNode(node.left, data);
return node;
} else {
node.right = this.removeNode(node.right,data);
return node;
}
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
}
// ์ถ๋ ฅ ์ ํธ ํจ์
function print(item){
console.log(item);
}
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
let nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
// let findValues = [3,12,25,23,33,45,99];
// findValues.forEach((value)=>{
// let hit = nums.find(value);
// print(`value ${value} ${hit==null?"is not":""} in bst`);
// })
nums.remove(23);
inOrder(nums.root);
/**
3
16
22
undefined
37
45
99
*/
// ๋งจ ์ผ์ชฝ์ ๋ฆฌํ ์ ๊ฑฐ
nums.remove(3);
inOrder(nums.root);
/**
16
22
23
37
45
99
*/
// ๋งจ ์ค๋ฅธ์ชฝ์ ๋ฆฌํ ์ ๊ฑฐ
nums.remove(99);
inOrder(nums.root);
/**
3
16
22
23
37
45
*/
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
nums.remove(37);
// ์ค๋ฅธ์ชฝ ์์์ด ํ๋์ธ ๋
ธ๋ ์ ๊ฑฐ
nums.remove(45);
inOrder(nums.root);
/**
3
16
22
23
99
*/
let nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
nums.remove(3);
inOrder(nums.root);
print('์ผ์ชฝ ์์์ด ํ๋์ธ ๋
ธ๋ ์ ๊ฑฐ')
// ์ผ์ชฝ ์์์ด ํ๋์ธ ๋
ธ๋ ์ ๊ฑฐ
nums.remove(16);
inOrder(nums.root);
/**
16
22
23
37
45
99
VM540:127 ์ผ์ชฝ ์์์ด ํ๋์ธ ๋
ธ๋ ์ ๊ฑฐ
22
23
37
45
99
*/
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
// ์์ ๋
ธ๋๊ฐ ๋ ๊ฐ์ธ ๋
ธ๋ ์ ๊ฑฐ
nums.remove(16);
inOrder(nums.root);
/**
3
undefined
22
23
37
45
99
*/
๋น๋์ ์นด์ดํธ
์ด๋ค ์ซ์๊ฐ ๋ฐ์ํ๋ ๋น๋์๋ฅผ ์ฒดํฌํ ๋ bst๋ฅผ ํ์ฉํ ์ ์๋ค.์๋ฅผ ๋ค๋ฉด ํ์๋ค ์ฑ์ ๋ถํฌ๋ฅผ bst๋ก ๋ํ๋ผ ์ ์๋๋ฐ, ์ ์๊ฐ bst์ ์๋ค๋ฉด ์ถ๊ฐํด์ฃผ๊ณ , ์๋ค๋ฉด ํด๋น ๋ ธ๋์ ๋น๋์++์ ํด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์๋ Node ํด๋์ค๊ฐ ๋น๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋๋ก ์ด์ง ๋ณ๊ฒฝ์ ํด์ค์ผ ํ๋ค.
class Node{
constructor(data,left,right){
this.data = data;
this count = 1; /** ๐ ์ถ๊ฐ */
this.left = left;
this.right = right;
}
show(){
return this.data;
}
}
์ฑ์ ๋ ธ๋๊ฐ BST์ ์ถ๊ฐ๋๋ฉด ๋น๋์ ์นด์ดํธ๋ 1๋ก ์ด๊ธฐํ๋๋ค.
BST ๋ ธ๋ insert์ ๋น๋์๋ ์ฆ๊ฐํ๋๋ก update ๋ฉ์๋๋ฅผ ์ถ๊ฐํด์ฃผ์.
// ๋
ธ๋ ์ถ๊ฐ ์ ๋น๋์ ++
update(data){
let grade = this.find(data);
grade.count ++;
return grade;
}
๐ ์ ์ฒด ์ฝ๋!
class Node{
constructor(data, left, right){
this.data = data;
this.left = left;
this.right = right;
this.count = 1;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
// ํ์ฌ ๋
ธ๋์ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ
show(){
return [`${this.data}์ `, this.count];
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
}
class BST{
constructor(){
this.root = null;
}
// ๋
ธ๋ ์ถ๊ฐ
insert(data){
let n = new Node(data,null,null); // ์ถ๊ฐํ ๋
ธ๋ ์์ฑ
if(this.root == null){ // ๋ฃจํธ๊ฐ ๋น์ด ์๋ค๋ฉด ์ถ๊ฐํ ๋
ธ๋๋ฅผ ๋ฃจํธ ๋
ธ๋๋ก ํ ๋น
this.root = n;
} else {
let current = this.root; // ๋ฃจํธ๊ฐ ๋น์ด ์์ง ์๋ค๋ฉด ํ์ฌ ๋ฃจํธ๋ฅผ ๊ธฐ์ค์ผ๋ก
let parent;
while(true){
parent = current; // ๋ถ๋ชจ๋ฅผ ํ์ฌ ๋ฃจํธ ๋
ธ๋๋ก ํ๊ณ
if(data < current.data){ // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค๋ฉด
current = current.left;
if(current == null){
parent.left = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค ์ผ์ชฝ์ ํ ๋นํ๋ค
break;
}
} else {
current = current.right; // ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฌ๋ค๋ฉด
if(current == null){
parent.right = n; // ๋ถ๋ชจ ๋
ธ๋ ๊ธฐ์ค์ผ๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ํ ๋น
break;
}
}
}
}
}
getMin(){
let current = this.root; // ๋ฃจํธ ๋
ธ๋๋ก๋ถํฐ ์์ํด์
while(!(current.left == null)){ // ๋ ์ด์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์์ ๋๊น์ง ๊ฒ์
current = current.left;
}
return current.data; // ๋งจ ์ผ์ชฝ์ leaf ๋
ธ๋๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ด๋ฏ๋ก ๋ฆฌํด
}
getMax(){
let current = this.root;
while(!(current.right == null)){
current = current.right;
}
return current.data;
}
find(data){
let current = this?.root;
if(current?.data == null) return null;
while(current.data != data){
if(data < current.data){ // ์ฐพ์ผ๋ ค๋ ๊ฐ์ด ํ์ฌ ๋
ธ๋๋ณด๋ค ์๋ค๋ฉด
current = current.left; // ์ผ์ชฝ ์๋ธ ํธ๋ฆฌ๋ก ์ด๋ํด์ ๊ฒ์
} else {
current = current.right; // ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํด์ ๊ฒ์
}
if(current == null){
return null;
}
}
return current;
}
remove(data){
this.root = this.removeNode(this.root, data);
}
removeNode(node, data){
if(node == null){
return null;
}
if(data == node.data){
// ๋
ธ๋๊ฐ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.left == null && node.right == null){
return null;
}
// ๋
ธ๋๊ฐ ์ผ์ชฝ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.left == null){
return node.right;
}
// ๋
ธ๋๊ฐ ์ค๋ฅธ์ชฝ ์์์ด ์์ ๊ฒฝ์ฐ
if(node.right == null){
return node.left;
}
// ๋
ธ๋๊ฐ ์์์ด ๋๊ฐ์ ๊ฒฝ์ฐ
let tempNode = this.getMin();
node.data = tempNode.data;
node.right = this.removeNode(node.right, tempNode.data);
return node;
}
else if(data< node.data){
node.left = this.removeNode(node.left, data);
return node;
} else {
node.right = this.removeNode(node.right,data);
return node;
}
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
// ๋
ธ๋ ์ถ๊ฐ ์ ๋น๋์ ++
update(data){
let grade = this.find(data);
grade.count ++;
return grade;
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
}
const arr =[];
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
// ์ถ๋ ฅ ์ ํธ ํจ์, ๋๋ฒ์งธ ์ธ์๋ฅผ true๋ก ๋๊ธฐ๋ฉด table ํ์์ผ๋ก ์ถ๋ ฅ
function print(item,table=false){
!table?console.log(item):console.table(item);
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
// inorder traversal
function inOrder(node){
if(!(node == null)){
inOrder(node.left);
arr.push(node.show());
// print(node.show());
inOrder(node.right);
}
}
// preOrder traversal
function preOrder(node){
if(!(node == null)){
print(node.show());
preOrder(node.left);
preOrder(node.right);
}
}
// postOrder traversal
function postOrder(node){
if(!(node == null)){
postOrder(node.left);
postOrder(node.right);
print(node.show());
}
}
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
let grades = new BST();
const scores = Array.from({length: 100},()=>Math.floor(Math.random()*101));
scores.forEach((score)=>{
let scoreExists = grades.find(score);
if(scoreExists == null){
grades.insert(score);
} else {
grades.update(score);
}
});
inOrder(grades.root);
print(arr,true);
////////////////////////////////////////////////// ๐ ์ถ๊ฐ //////////////////////////////////////////////////
์ถ๋ ฅ ๊ฒฐ๊ณผ
๐ ๋ง์น๋ฉด์
TMI...traversal gif ์ฝ์ ์ค ์๋ฌ ๋ฐ์ ใ ใ ์ด๋ฏธ ๊ธ์ ๋ฑ๋กํ ์ํ๋ผ์ ์๋ ์ ์ฅ์ด ์๋ผ์ bst ํ์ ์ด์ ๋ถํฐ ๊ธ์ ๋๋ฒ ์ฐ๋ ์ค ใ ใ ใ ใ
bst์ ๋ํด์๋ ํ์คํ ์๊ณ ๊ฐ๋ ์๊ฐ์ด ๋ ๊ฑฐ ๊ฐ๋ค ๐๐๐๐๐๐
๐ Reference
- Data Structures and Algorithms Using Javaโ Script by Michael McMillian (O’Reilly). Copyright 2014 Michael McMillan, 978-1-449-36493-9
'๐ค data structures & algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Data Structures & Algorithms with Javascript : Sorting Algorithms (Basic) (0) | 2024.07.27 |
---|---|
Data Structures & Algorithms with Javascript : ์ค๊ฐ(?) ์ ๊ฒ ๐ช (0) | 2024.07.25 |
Data Structures & Algorithms with Javascript : Sets (2) | 2024.07.24 |
Data Structures & Algorithms with Javascript : Hashing (0) | 2024.07.23 |
Data Structures & Algorithms with Javascript : Dictionaries (0) | 2024.07.22 |