Data Structure in JavaScript
μλ°μ€ν¬λ¦½νΈμ μλ£κ΅¬μ‘°
- λ³Έ κΈμ Data Structure in JavaScript κΈμ λ²μν λ΄μ©μ λλ€.
- This article is a translation of Data Structure in JavaScript
μμνλ©°
βλΉμ§λμ€ λ‘μ§μ΄ μ μ λ λ°±λ¨μμ νλ‘ νΈλ‘ μ΄λν¨μ λ°λΌ νλ‘ νΈ μμ§λμ΄λ§ μ λ¬Έμ§μμ΄ λμ± μ€μν΄μ§κ² λμλ€.
νλ‘ νΈ μμ§λμ΄λ‘μ¨, μ°λ¦¬λ 리μνΈ κ°μ μμ°μ±μλ λ·° λΌμ΄λΈλ¬λ¦¬μ μμ‘΄νλ€. λ·° λΌμ΄λΈλ¬λ¦¬λ€μ κ²°κ΅ λ°μ΄ν° κ΄λ¦¬λ₯Ό μν΄ λ¦¬λμ€μ κ°μ μν λΌμ΄λΈλ¬λ¦¬μ μμ‘΄νλ€.
β리μνΈμ 리λμ€λ UI μ λ°μ΄νΈκ° λ°μ΄ν° λ³κ²½μ λ°μνλ λ°μν νλ‘κ·Έλλ° ν¨λ¬λ€μμ ν¨κ» κ°μ νλ€. μ μ λ, λ°±μλλ λ¨μν API μλ²λ‘ μλνμ¬ λ°μ΄ν°λ₯Ό κ²μνκ³ μ λ°μ΄νΈνλ μλν¬μΈνΈλ§ μ 곡νλ€. μ¬μ€μ, λ°±μλλ λ¨μ§ λ°μ΄ν°λ² μ΄μ€λ₯Ό νλ‘ νΈλ‘ βν¬μλ©β νκ³ , νλ‘ νΈ μμ§λμ΄κ° λͺ¨λ λ‘μ§μ 컨νΈλ‘€νκΈΈ κΈ°λνλ€. λ§μ΄ν¬λ‘μλΉμ€μ GraphQLμ μΈκΈ° μμΉμ΄ μ΄λ¬ν μ¦κ° μΆμΈλ₯Ό μ¦λͺ νλ€.
βμ΄μ νλ‘ νΈ μμ§λμ΄λ€μ HTMLκ³Ό CSSμ λν λ―Έμ μ΄ν΄λΏλ§ μλλΌ, μλ°μ€ν¬λ¦½νΈλ₯Ό μμ£Ό μ λ€λ£¨μ΄μΌ νλ€. ν΄λΌμ΄μΈνΈμ λ°μ΄ν°μ€ν μ΄κ° μλ²μ λ°μ΄ν°λ² μ΄μ€μ β볡μ β λλ©΄μ, κ΄μ© μλ£κ΅¬μ‘°μ λν μΉλ°ν μ§μμ΄ μ€μ¬μ μν μ νκ² λμλ€. μ€μ λ‘ μμ§λμ΄μ κ²½ν μμ€μ νΉμ μλ£κ΅¬μ‘°λ₯Ό μΈμ , μ μ¬μ©ν΄μΌνλμ§ κ΅¬λ³ν μ μλ λ₯λ ₯μΌλ‘ μ μΆν μμλ€.
μ΄κΈ νλ‘κ·Έλλ¨Έλ μ½λμ λν΄ κ±±μ νμ§λ§ κ³ κΈ νλ‘κ·Έλλ¨Έλ μλ£κ΅¬μ‘°μ κ·Έλ€μ κ΄κ³λ₯Ό κ±±μ νλ€.
- Linux, Git μ°½μμ 리λμ€ ν λ°μ¦
ν° νλ‘, κΈ°λ³Έμ μΈ 3κ°μ§ μ νμ μλ£κ΅¬μ‘°κ° μλ€.
- Array: Stack κ³Ό Queue λ μ€μ§ μμ΄ν μ μ΄λ»κ² μ½μ /μμ νλκ° λ§ λ€λ₯Έ λ°°μ΄ κ°μ μλ£κ΅¬μ‘°λ€μ΄λ€.
- LinkedList: λ§ν¬λ 리μ€νΈ, νΈλ¦¬ κ·Έλ¦¬κ³ κ·Έλνλ λ€λ₯Έ λ Έλμ λν μ°Έμ‘°λ₯Ό μ μ§νλ λ Έλλ‘ μ΄λ£¨μ΄μ§ ꡬ쑰체μ΄λ€.
- Hash: ν΄μ¬ν μ΄λΈμ λ°μ΄ν°λ₯Ό μ μ₯νκ³ μ°ΎκΈ° μν΄ ν΄μ¬ ν¨μμ μμ‘΄νλ€.
β볡ν©μ± μΈ‘λ©΄μμ, Stack
κ³Ό Queue
λ κ°μ₯ κ°λ¨νλ©° Linked List
λ‘ κ΅¬μ±ν μ μλ€. Tree
μ Graph
λ λ§ν¬λ 리μ€νΈμ κ°λ
μ νμ₯μν¨ κ²μ΄κΈ° λλ¬Έμ κ°μ₯ 볡μ‘νλ€. Hash Table
μ μ΄λ° μλ£κ΅¬μ‘°λ€μ νμ©νμ¬ μμ μ μΌλ‘ λμκ°μΌνλ€.
βν¨μ¨μ± μΈ‘λ©΄μμ, Linked Listλ λ°μ΄ν°μ κΈ°λ‘ λ° μ μ₯μ κ°μ₯ μ΅μ νλμ΄μμΌλ©° Hash Tableμ λ°μ΄ν°μ νμκ³Ό κ²μμ κ°μ₯ ν¨κ³Όμ μ΄λ€.
μ΄μ λ₯Ό μ€λͺ νκ³ μκΈ°λ₯Ό μ€λͺ νκΈ° μν΄, μ΄ κΈμ μμμ μΈκΈν μμ‘΄μ±μ μμλ₯Ό λ°λ₯Ό κ²μ΄λ€. μμν΄λ³΄μ!
Stack
βμμ¬μ μ¬μ§μμ΄ μλ°μ€ν¬λ¦½νΈμμ κ°μ₯ μ€μν Stack
μ μ°λ¦¬κ° μ€ννλ νμ
μ μ€μ½νλ₯Ό νΈμ¬νλ call stack μΌ κ²μ΄λ€. νλ‘κ·Έλλ°μ μΌλ‘ μ€νμ λ¨μν push
μ pop
μ λ κ°μ§ μ μ±
μ κ°μ§ λ°°μ΄μ΄λ€. Pushλ λ°°μ΄μ νμ μμλ₯Ό μΆκ°νλ€. λ°λ©΄ Popμ κ°μ μμΉμμ μμλ₯Ό μ κ±°νλ€. μ¦, Stacks μ βLast In, First Outβ μ μ±
μ λ°λ₯Έλ€(LIFO).
βμλλ Stack
μ½λμ μλ€. μ°λ¦¬λ μ€νμ μμλ₯Ό λ€μ§μ μ μλ€λ μ μ μ μν΄μΌνλ€. λ°ν
μ΄ νμΌλ‘κ°κ³ νμ΄ λ°ν
μ κ°λ€λ λ»μ΄λ€.(μμ - μ μλ μ€νμ reverse λ μΌλνλ―.)
class Stack {
constructor(...items) {
this.reverse = false;
this.stack = [...items];
}
push(...items) {
return this.reverse ? this.stack.unshift(...items) : this.stack.push(...items);
}
pop(...items) {
return this.reverse ? this.stack.shift() : this.stack.pop();
}
}
(μμ - λ³Έ κΈμ βμλ°μ€ν¬λ¦½νΈ λ΄λΆμμ μ°μ΄λ μλ£κ΅¬μ‘°β κ°λ μ μ΄ν΄νλ ν¬μ€ν°λΌ API ꡬνκΉμ§λ λ€λ£¨μ§ μλλ€.)
βμμ΄ν
μ μ«μκ° μ¦κ°ν¨μ λ°λΌ, push
/pop
μ unshift
/shift
λ³΄λ€ λ μ±λ₯μ΄ μ’μμ§κ² λλ€. κ·Έ μ΄μ λ νμμ κ²½μ° λͺ¨λ μμ΄ν
μ΄ λ€μ μΈλ±μ±μ ν΄μΌνκΈ° λλ¬Έμ΄λ€.(push/pop μ μ΅μλ¨ index λ§ λ³νκΈ° λλ¬Έ)
Queue
βμλ°μ€ν¬λ¦½νΈλ non-blockingμ μ§μνλ event-driven λ°©μμ νλ‘κ·Έλλ° μΈμ΄μ΄λ€. λ΄λΆμ μΌλ‘, λΈλΌμ°μ λ νλμ μ°λ λλ§ κ΄λ¦¬νκΈ° λλ¬Έμ λΈλΌμ°μ λ μλ°μ€ν¬λ¦½νΈ μ½λ μ 체λ₯Ό μ€ννκΈ° μν΄ μ€μ§ νλμ μ°λ λλ§ κ΄λ¦¬νλ©°, event queueλ₯Ό μ¬μ©νμ¬ listener
λ₯Ό λ±λ‘(enqueue) νκ³ event loopλ‘ λ±λ‘λ event
λ€μ listen νλ€.
βμ±κΈ μ°λ λ νκ²½μμ λΉλκΈ°λ₯Ό μ§μνκΈ° μν΄(CPU μμκ³Ό μΉ κ²½νμ ν₯μμ μν΄μ), listener function
λ€μ call stackμ΄ λΉμ΄μμ λλ§ μ κ±°(dequeue) λλ©° μ€νλλ€. Promise
λ€μ μ΄ event-driven architectureμ μμ‘΄νμ¬ λ€λ₯Έ μμ
μ μ°¨λ¨νμ§ μλ λΉλκΈ° μ½λμ βλκΈ°μβ μ€νμ νλ½νλ€.
βνλ‘κ·Έλλ°μ μΌλ‘, Queue
λ λκ°μ λ¨μν μμ
(unshift
and pop
)μ΄ μλ λ°°μ΄μ λΆκ³Όνλ€. Unshiftλ μμ΄ν
λ€μ λ°°μ΄μ λ μ λ±λ‘(enqueue) νλ λ°λ©΄, Popμ λ°°μ΄μ μμ μμ μ κ±°(dequeue)νλ€. μ¦, Queueλ βFirst In, First Outβ(FIFO) μ μ±
μ λ°λ₯Έλ€. λ§μ½ λ°©ν₯μ΄ λ€μ§μ΄μ§λ©΄, μ°λ¦¬λ unshift
μ pop
μ κ°κ° push
μ shift
λ‘ λμΉν μ μλ€.
μλλ Queue
μ½λμ μμ΄λ€.
class Queue {
constructor(...items) {
this.reverse = false;
this.queue = [...items];
}
enqueue(...items) {
return this.reverse ? this.queue.push(...items) : this.queue.unshift(...items);
}
dequeue() {
return this.reverse ? this.queue.shift() : this.queue.pop();
}
}
Linked List
βLinked List
λ λ°°μ΄κ°μ΄ λ°μ΄ν°λ€μ μμ°¨μ μΌλ‘ μ μ₯νλ€. λ§ν¬λ 리μ€νΈλ μΈλ±μ€λ₯Ό μ μ§νλ λμ λ€λ₯Έ μμλ₯Ό κ°λ¦¬ν€λ ν¬μΈν° λ₯Ό κ°μ§κ³ μλ€. 첫 λ²μ§Έ λ
Έλλ headλΌκ³ λΆλ¦¬λ λ°λ©΄ λ§μ§λ§ λ
Έλλ tailμ΄λΌ λΆλ¦°λ€. singly-linked list μμ κ° λ
Έλλ λ€μλ
Έλλ₯Ό κ°λ¦¬ν€λ μ€μ§ νλμ ν¬μΈν°λ§ κ°μ§κ³ μλ€. μ¬κΈ°μ headλ μ°λ¦¬κ° 리μ€νΈμ λλ¨Έμ§λ€λ‘ κ±Έμ΄κ°κΈ° μν μμμ μ΄λ€. doubly-linked listμ κ²½μ° μ΄μ (previous) λ
Έλλ‘ κ°λ ν¬μΈνΈλ κ°μ§κ³ μλ€. κ·Έλ¬λ―λ‘ μ°λ¦¬λ tailμμ μμν΄ βλ€μμβ μμΌλ‘ κ° μ μλ€.
βλ§ν¬λ 리μ€νΈλ μ½μ κ³Ό μμ μ μμμκ° O(1)μ κ°μ§λ€ μλνλ©΄ λ¨μν ν¬μΈν°λ€λ§ λ°κΎΈλ©΄ λκΈ° λλ¬Έμ΄λ€. λ°°μ΄μμ κ°μ μλμ νκΈ° μν΄μ μ ν μκ° O(N)μ΄ νμνλ€ μλλ©΄ μ΄νμ μμ΄ν λ€μ΄ ν μΉΈμ© λ°λ €λμΌ νκΈ° λλ¬Έμ΄λ€. λν, λ§ν¬λ리μ€νΈλ 곡κ°(λ©λͺ¨λ¦¬)μ΄ μλ ν λν μ μλ€. κ·Έλ¬λ, μλμΌλ‘ 리μ¬μ΄μ§μ νλ βλμ β λ°°μ΄λ μκ°μΈλ‘ λΉμΌ κ°μ μΉλ€μΌ ν μ μλ€. λ¬Όλ‘ , μ΄κ²λ€μ νμ λ±κ°κ΅νμ΄λ€. λ§ν¬λ 리μ€νΈμ μμλ₯Ό λ³κ²½νκ±°λ μ°Ύμ보μ. μ°λ¦¬λ μλ§λ μ ν μκ°μΌλ‘ μ 체 κΈΈμ΄λ₯Ό νμν΄μΌ ν μλ μλ€. λ°λ©΄ μΈλ±μ€ λ°°μ΄μμλ λ°λ‘ μ°Ύμκ° μ μλ€.
βλ°°μ΄μ²λΌ, λ§ν¬λ 리μ€νΈλ stack κ°μ΄ μ‘°μν μ μλ€. head λ₯Ό μ½μ
, μμ νλ 곡κ°μ΄ νλμ΄λ―λ‘ μ½κ² ꡬνν μ μλ€. λν λ§ν¬λ리μ€νΈλ queueμ κ°μ΄ μλ ν μ μλ€. μ΄λ doubly-linked list λ‘ μ΄λ£¨μ΄ μ§ μ μλλ°, tailμμ μ½μ
μ΄ μΌμ΄λκ±°λ headμμ μμ κ° μΌμ΄λ λ νΉμ λ°λμΌ λ κ°λ₯νλ€. λ§μ μ«μλ€μ΄ μ‘΄μ¬νλ μμμμ μ΄ κ΅¬ν λ°©λ²μ λ°°μ΄μ μ¬μ©ν΄ νλ₯Ό ꡬννλ κ²λ³΄λ€ λ μ’μ μ±λ₯μ 보μΈλ€. μ΄μ λ λ°°μ΄μμ shift
μ unshift
μλμ΄ μΌμ΄λ λ μΈλ±μ€λ₯Ό μ¬λ°°μ΄ νκΈ° μν΄ μ ν μκ°μ΄ νμνκΈ° λλ¬Έμ΄λ€.
βλ§ν¬λ리μ€νΈλ ν΄λΌμ΄μΈνΈμ μλ²μμ λͺ¨λ μΈλͺ¨μλ€. ν΄λΌμ΄μΈνΈμμ Redux κ°μ μνκ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬λ€μ λ―Έλ€μ¨μ΄ λ‘μ§μ λ§ν¬λ 리μ€νΈ λ°©μμΌλ‘ ꡬννλ€. actionμ΄ λμ€ν¨μΉ λ λ, λͺ¨λ reducerμ λλ¬ν λκΉμ§ νλμ λ―Έλ€μ¨μ΄μμ λ€μ λ―Έλ€μ¨μ΄λ‘ μ°κ²°λλ€. μλ²μ κ²½μ° Express κ°μ μΉ νλ μμν¬λ λΉμ·ν λ―Έλ€μ¨μ΄ λ‘μ§μ κ°μ§κ³ μλ€. request λ₯Ό λ°μμ λ, μ΄κ²λ€μ reponse λ°μ λ κΉμ§ λ―Έλ€μ¨μ΄λ₯Ό νκ³ λ€λλ€.
μλλ Doubly-Linked List
μ μ½λ μμ΄λ€.
class Node {
constructor(value, next, prev) {
this.value = value;
this.next = next;
this.prev = prev;
}
}
class LinkedList {
constructor() {
this.head = null;
this.tail = null;
}
addToHead(value) {
const node = new Node(value, null, this.head);
if (this.head) this.head.next = node;
else this.tail = node;
this.head = node;
}
addToTail(value) {
const node = new Node(value, this.tail, null);
if (this.tail) this.tail.prev = node;
else this.head = node;
this.tail = node;
}
removeHead() {
if (!this.head) return null;
const value = this.head.value;
this.head = this.head.prev;
if (this.head) this.head.next = null;
else this.tail = null;
return value;
}
removeTail() {
if (!this.tail) return null;
const value = this.tail.value;
this.tail = this.tail.next;
if (this.tail) this.tail.prev = null;
else this.head = null;
return value;
}
search(value) {
let current = this.head;
while (current) {
if (current.value === value) return value;
current = current.prev;
}
return null;
}
indexOf(value) {
const indexes = [];
let current = this.tail;
let index = 0;
while (current) {
if (current.value === value) indexes.push(index);
current = current.next;
index++;
}
return indexes;
}
}
Tree
βTree
λ λ§μ child nodesμ μ μ§νκ³ μλ κ³μΈ΅μ ꡬ쑰λΌλ κ²μ μ μΈνκ³€ linked listκ°λ€. μ¦, κ° λ
Έλλ ν λͺ
μ΄μμ λΆλͺ¨λ₯Ό κ°μ§ μ μλ€. Document Object Model(DOM)μ΄ μ΄ κ΅¬μ‘°μ΄λ€. root λ html
λ
Έλμ΄λ©° μμλ€λ‘ head
μ body
λ
Έλκ° μλ€. μ΄λ€μ μΉμν λͺ¨λ html νκ·Έ λ‘ λμ± μΈλΆνλλ€. μ€μ λ‘ λ¦¬μνΈ μ»΄ν¬λνΈ λν prototype μμκ³Ό κ΅¬μ± μ νΈλ¦¬ ꡬ쑰λ₯Ό μμ±νλ€. λ¬Όλ‘ DOMμ μΈλ©λͺ¨λ¦¬ ννμΈ λ¦¬μνΈμ κ°μDOM λν νΈλ¦¬ ꡬ쑰μ΄λ€.
βBinary Search Treeλ κ° λ Έλκ° λ κ°μ μμ μ΄μμ κ°μ§ μ μκΈ° λλ¬Έμ νΉλ³νλ€. left childμ κ°μ λ°λμ λΆλͺ¨μ κ°λ³΄λ€ μκ±°λ κ°μμΌνλ€ λ°λ©΄ right childλ λ°λμ λΆλͺ¨μ κ°λ³΄λ€ 컀μΌνλ€. μ΄μκ°μ΄ ꡬ쑰νλκ³ κ· νμ΄ λ§μΆ°μ‘λ€λ©΄, μ°λ¦¬λ μ΄λ ν κ°μ΄λ search μ λ‘κ·Έ μκ°λ§μ μ°Ύμ μ μλ€. μ΄μ λ κ° λΈλμΉλ₯Ό μνμ μμ μ λ°μ 무μν μ μκΈ° λλ¬Έμ΄λ€. μ½μ κ³Ό μμ λν λ‘κ·Έμκ°μ κ°λ₯νλ€. κ²λ€κ°, κ°μ₯ μΌμͺ½, κ°μ₯ μ€λ₯Έμͺ½ λ Έλκ° κ°κ° μ΅μ νΉμ μ΅λ κ°μ΄λ―λ‘ κ°μ μ½κ² μ°Ύμ μ μλ€.
βνΈλ¦¬μ μνλ μμ§ λλ μνμ μ μ°¨λ‘ λ°μν μ μλ€. μΈλ‘ λ°©ν₯μ Depth-First Traversal(DFT: DFS) μμ μ¬κ· μκ³ λ¦¬μ¦μ λ°λ³΅λ¬Έλ³΄λ€ λ μ°μνλ€. λ Έλλ€μ pre-order, in-order, post-order μΌλ‘ μνλλ€. λ§μ½ 리νλ Έλλ₯Ό κ²μ¬νκΈ° μ μ 루νΈλ Έλλ₯Ό νμν΄μΌ νλ€λ©΄, μ°λ¦¬λ pre-order λ₯Ό μ νν κ²μ΄λ€. κ·Έλ¬λ λ§μ½ 루νΈμ μ 리νλ ΈλλΆν° νμν΄μΌ νλ€λ©΄ post-orderλ₯Ό μ νν΄μΌ νλ€. in-order λ μ΄λ¦μ΄ μμνλ―, λ Έλλ€μ μμ°¨μ μΌλ‘ μνν μ μλ€. μ΄ μμ±λ€μ μ΄μ§νμνΈλ¦¬λ₯Ό μ λ ¬μ μ΅μ ν λκ² λ§λ λ€.
βμν λ°©ν₯μ Breadth-First Traversal(BFT: BFS)μμ λ°λ³΅λ¬Έμ μ¬κ·λ³΄λ€ λ μ°μνλ€. μ΄κ²μ κ° μνμ λͺ¨λ μμ λ
Έλλ€μ νΈλνΉνκΈ° μν΄μ queue
μ μ¬μ©μ μꡬνλ€. μ΄ νμ νμν λ©λͺ¨λ¦¬λ μ¬μνμ§ μμ μ μλ€. νμ§λ§ νΈλ¦¬μ λͺ¨μμ΄ κΉμ΄λ³΄λ€ λλ€λ©΄, BFTκ° DFT λ³΄λ€ λ λμ μ νμ΄λ€. λν, BFT κ° λ λ
Έλ μ¬μ΄λ₯Ό μ΄λνλ κ²½λ‘λ κ°λ₯ν κ°μ₯ μ§§μ 거리μ΄λ€.
μλλ Binary Search Tree
μ μ½λ μμ΄λ€.
class Tree {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
insert(value) {
if (value <= this.value) {
if (!this.left) this.left = new Tree(value);
else this.left.insert(value);
} else {
if (!this.right) this.right = new Tree(value);
else this.right.insert(value);
}
}
contains(value) {
if (value === this.value) return true;
if (value < this.value) {
if (!this.left) return false;
else return this.left.contains(value);
} else {
if (!this.right) return false;
else return this.right.contains(value);
}
}
depthFirstTraverse(order, callback) {
order === "pre" && callback(this.value);
this.left && this.left.depthFirstTraverse(order, callback);
order === "in" && callback(this.value);
this.right && this.right.depthFirstTraverse(order, callback);
order === "post" && callback(this.value);
}
breadthFirstTraverse(callback) {
const queue = [this];
while (queue.length) {
const root = queue.shift();
callback(root.value);
root.left && queue.push(root.left);
root.right && queue.push(root.right);
}
}
getMinValue() {
if (this.left) return this.left.getMinValue();
return this.value;
}
getMaxValue() {
if (this.right) return this.right.getMaxValue();
return this.value;
}
}
mocha.setup("bdd");
const { assert } = chai;
const tree = new Tree(5);
for (const value of [3, 6, 1, 7, 8, 4, 10, 2, 9]) tree.insert(value);
/*
5
3 6
1 4 7
2 8
10
9
*/
describe("Binary Search Tree", () => {
it("Should implement insert", () => {
assert.equal(tree.value, 5);
assert.equal(tree.left.value, 3);
assert.equal(tree.right.value, 6);
assert.equal(tree.left.left.value, 1);
assert.equal(tree.right.right.value, 7);
assert.equal(tree.right.right.right.value, 8);
assert.equal(tree.left.right.value, 4);
assert.equal(tree.right.right.right.right.value, 10);
assert.equal(tree.left.left.right.value, 2);
assert.equal(tree.right.right.right.right.left.value, 9);
});
it("Should implement contains", () => {
assert.equal(tree.contains(2), true);
assert.equal(tree.contains(9), true);
assert.equal(tree.contains(0), false);
assert.equal(tree.contains(11), false);
});
it("Should implement depthFirstTraverse", () => {
const _pre = [];
const _in = [];
const _post = [];
tree.depthFirstTraverse("pre", value => _pre.push(value));
tree.depthFirstTraverse("in", value => _in.push(value));
tree.depthFirstTraverse("post", value => _post.push(value));
assert.deepEqual(_pre, [5, 3, 1, 2, 4, 6, 7, 8, 10, 9]);
assert.deepEqual(_in, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
assert.deepEqual(_post, [2, 1, 4, 3, 9, 10, 8, 7, 6, 5]);
});
it("Should implement breadthDepthTraverse", () => {
const result = [];
tree.breadthFirstTraverse(value => result.push(value));
assert.deepEqual(result, [5, 3, 6, 1, 4, 7, 2, 8, 10, 9]);
});
it("Should implement getMinValue", () => {
assert.equal(tree.getMinValue(), 1);
});
it("Should implement getMaxValue", () => {
assert.equal(tree.getMaxValue(), 10);
});
});
Graph
βλ§μ½ νΈλ¦¬μ λΆλͺ¨κ° νλλ³΄λ€ λ λ§μ΄ κ°μ§ μ μλ€λ©΄, μ΄κ²μ΄ λ°λ‘ Graph
μ΄λ€. κ·Έλνμμ λ
Έλλ€μ μ΄μ΄μ£Όλ Edgeλ λ
Έλλ€μ΄ λ°©ν₯, 무방ν₯, κ°μ€μΉ, λΉκ°μ€μΉ λ₯Ό κ°μ§κ² νλ€. Edge λ€μ vectorμ μ μ¬ν λ°©ν₯κ³Ό κ°μ€μΉλ₯Ό κ°μ§λ€.
β
μΆκ° μμ
κ°μ¬ν©λλ€.