νž™(Heap)

0. μš”μ•½

μ΅œμ†Œ νž™ κ΅¬ν˜„ν•˜κΈ°

class Heap {
  constructor() {
    this.heap = [null];
  }

  // νž™μ— μš”μ†Œ μΆ”κ°€ν•˜κΈ°
  push(value) {
    this.heap.push(value);
    let cur_index = this.heap.length - 1;
    let parents_index = Math.floor(cur_index / 2);

    while (cur_index !== 1 && this.heap[parents_index] > value) {
      [this.heap[parents_index], this.heap[cur_index]] = [
        this.heap[cur_index],
        this.heap[parents_index],
      ];
      cur_index = parents_index;
      parents_index = Math.floor(cur_index / 2);
    }
  }

  // νž™μ— μš”μ†Œ μ œκ±°ν•˜κΈ°
  pop() {
    const value = this.heap[1];

    if (this.heap.length <= 2) this.heap = [null];
    else this.heap[1] = this.heap.pop();

    let cur_index = 1;
    let left_index = cur_index * 2;
    let right_index = cur_index * 2 + 1;

    if (!this.heap[left_index]) return value;
    if (!this.heap[right_index]) {
      if (this.heap[left_index] < this.heap[cur_index]) {
        [this.heap[left_index], this.heap[cur_index]] = [
          this.heap[cur_index],
          this.heap[left_index],
        ];
      }
      return value;
    }

    while (
      this.heap[left_index] < this.heap[cur_index] ||
      this.heap[right_index] < this.heap[cur_index]
    ) {
      let min_index =
        this.heap[left_index] > this.heap[right_index]
          ? right_index
          : left_index;

      [this.heap[min_index], this.heap[cur_index]] = [
        this.heap[cur_index],
        this.heap[min_index],
      ];

      cur_index = min_index;
      left_index = cur_index * 2;
      right_index = cur_index * 2 + 1;
    }
    return value;
  }
}

1. κ°œμš”

μ™„μ „ 이진 트리의 일쒅인 νž™μ— λŒ€ν•΄ μ •λ¦¬ν•œλ‹€.

μ°Έκ³ ν•  λ§Œν•œ μ½”λ”© ν…ŒμŠ€νŠΈ 문제


2. μš°μ„ μˆœμœ„ νλž€?

νž™μ— λŒ€ν•΄ μ‚΄νŽ΄λ³΄κΈ° μ „ μš°μ„ μˆœμœ„ 큐에 λŒ€ν•΄ λ¨Όμ € μ‚΄νŽ΄λ³΄μž. μš°μ„ μˆœμœ„ 큐을 λ¨Όμ € μ‚΄νŽ΄λ³΄λŠ” μ΄μœ λŠ” νž™μ΄ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ κ³ μ•ˆλœ μ™„μ „ 이진 트리 ν˜•νƒœμ˜ 자료ꡬ쑰이기 λ•Œλ¬Έμ΄λ‹€.

  • 큐(Queue): λ¨Όμ € λ“€μ–΄μ˜€λŠ” 데이터가 λ¨Όμ € λ‚˜κ°€λŠ” FIFO ν˜•μ‹μ˜ 자료ꡬ쑰

  • μš°μ„ μˆœμœ„ 큐(Priority Queue): λ¨Όμ € λ“€μ–΄μ˜¨ 데이터가 μ•„λ‹ˆλΌ, μš°μ„ μˆœμœ„κ°€ 높은 데이터가 λ¨Όμ € λ‚˜κ°

주의 ν•΄μ•Όν•  점은 μš°μ„ μˆœμœ„ νλŠ” μžλ£Œκ΅¬μ‘°κ°€ μ•„λ‹Œ κ°œλ…μ΄λΌλŠ” 것이닀. λ˜ν•œ μš°μ„ μˆœμœ„ 큐가 νž™μ΄λΌλŠ” 것도 μ•„λ‹ˆλ‹€. 즉, μš°μ„ μˆœμœ„ νλΌλŠ” κ°œλ…μ„ μ μš©ν•˜κΈ° μœ„ν•΄ νž™ 자료ꡬ쑰λ₯Ό μ‚¬μš©ν•œλ‹€λŠ” κ²ƒμœΌλ‘œ μ΄ν•΄ν•˜λ„λ‘ ν•˜μž.

μš°μ„ μˆœμœ„ νλŠ” λ°°μ—΄, μ—°κ²° 리슀트, νž™μœΌλ‘œ κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜λ‹€. 이 쀑 νž™μœΌλ‘œ κ΅¬ν˜„ν•˜λŠ” 것이 κ°€μž₯ νš¨μœ¨μ μ΄λ‹€.

μš°μ„ μˆœμœ„ 큐 κ΅¬ν˜„ 비ꡐ

μš°μ„ μˆœμœ„ 큐의 μ‚¬μš© μ‚¬λ‘€λŠ” μ•„λž˜μ™€ κ°™λ‹€.

  • μ‹œλ¬Όλ ˆμ΄μ…˜ μ‹œμŠ€ν…œ

  • λ„€νŠΈμ›Œν¬ νŠΈλž˜ν”½ μ œμ–΄

  • 운영 μ²΄μ œμ—μ„œμ˜ μž‘μ—… μŠ€μΌ€μ₯΄λ§


3. νž™μ΄λž€?

  • μ™„μ „ 이진 트리의 일쒅

  • μ—¬λŸ¬ κ°’ 쀑, μ΅œλŒ€κ°’κ³Ό μ΅œμ†Œκ°’μ„ λΉ λ₯΄κ²Œ 찾아내도둝 λ§Œλ“€μ–΄μ§„ 자료ꡬ쑰

  • μΌμ’…μ˜ λ°˜μ •λ ¬ μƒνƒœ(λŠμŠ¨ν•œ μ •λ ¬ μƒνƒœ)λ₯Ό μœ μ§€

    • 큰 값이 μƒμœ„ λ ˆλ²¨μ— 있고 μž‘μ€ 값이 ν•˜μœ„ λ ˆλ²¨μ— μžˆλ‹€λŠ” 정도

  • μ€‘λ³΅λœ 값을 ν—ˆμš©(이진 탐색 νŠΈλ¦¬μ—μ„œλŠ” μ€‘λ³΅λœ 값을 ν—ˆμš©ν•˜μ§€ μ•ŠμŒ)


4. νž™μ˜ μ’…λ₯˜

νž™μ˜ μ’…λ₯˜
  1. μ΅œλŒ€ νž™(max heap)

    • λΆ€λͺ¨ λ…Έλ“œμ˜ ν‚€ 값이 μžμ‹ λ…Έλ“œμ˜ ν‚€ 값보닀 ν¬κ±°λ‚˜ 같은 μ™„μ „ 이진 트리

  2. μ΅œμ†Œ νž™(min heap)

    • λΆ€λͺ¨ λ…Έλ“œμ˜ ν‚€ 값이 μžμ‹ λ…Έλ“œμ˜ ν‚€ 값보닀 μž‘κ±°λ‚˜ 같은 μ™„μ „ 이진 트리


5. νž™ κ΅¬ν˜„ν•˜κΈ°

νž™μ„ κ΅¬ν˜„ ν•˜κΈ° μ „ λͺ‡ κ°€μ§€ 사항을 짚고 λ„˜μ–΄κ°€μž.

  • νž™μ„ μ €μž₯ν•˜λŠ” ν‘œμ€€μ μΈ 자료ꡬ쑰둜 배열을 μ΄μš©ν•œλ‹€.

  • κ΅¬ν˜„μ„ μ‰½κ²Œ ν•˜κΈ° μœ„ν•΄ λ°°μ—΄μ˜ 첫 번째 인덱슀인 0은 μ‚¬μš©λ˜μ§€ μ•ŠλŠ”λ‹€.

  • νŠΉμ • μœ„μΉ˜μ˜ λ…Έλ“œ λ²ˆν˜ΈλŠ” μƒˆλ‘œμš΄ λ…Έλ“œκ°€ μΆ”κ°€λ˜μ–΄λ„ λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • λΆ€λͺ¨ λ…Έλ“œμ™€ μžμ‹ λ…Έλ“œμ˜ 관계

    • μ™Όμͺ½ μžμ‹μ˜ 인덱슀 = (λΆ€λͺ¨μ˜ 인덱슀) * 2

    • 였λ₯Έμͺ½ μžμ‹μ˜ 인덱슀 = (λΆ€λͺ¨μ˜ 인덱슀) * 2 + 1

    • λΆ€λͺ¨μ˜ 인덱슀 = Math.floor(μžμ‹μ˜ 인덱슀 / 2)

      λΆ€λͺ¨ λ…Έλ“œμ™€ μžμ‹ λ…Έλ“œμ˜ 관계

μœ„μ˜ λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ μ΅œμ†Œ νž™μ„ κ΅¬ν˜„ν•œλ‹€.


5-1. νž™μ˜ κΈ°λ³Έ ꡬ쑰

this.heap을 λ°°μ—΄λ‘œ μ΄μš©ν•˜μ—¬ 선언을 ν•˜κ³  첫 번째 μš”μ†ŒλŠ” null둜 μ €μž₯ν•œλ‹€.


5-2. νž™μ— μš”μ†Œ μΆ”κ°€ν•˜κΈ°

μ΅œμ†Œ νž™μ€ λΆ€λͺ¨ λ…Έλ“œκ°€ 제일 μž‘μ•„μ•Ό ν•œλ‹€. ν˜„μž¬ λ…Έλ“œμ™€ λΆ€λͺ¨ λ…Έλ“œμ˜ 값을 λΉ„κ΅ν•˜μ—¬ λΆ€λͺ¨ λ…Έλ“œμ˜ 값이 크닀면 κ·Έ λ‘˜μ„ μ„œλ‘œ λ°”κΎΈμ–΄ μ€€λ‹€.

λ§Œμ•½ ν˜„μž¬ λ…Έλ“œμ˜ μΈλ±μŠ€κ°€ 1μ΄κ±°λ‚˜ ν˜„μž¬ λ…Έλ“œκ°€ λΆ€λͺ¨ λ…Έλ“œ 보닀 값이 μž‘λ‹€λ©΄ 반볡문 더 이상 μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.


5-3. νž™μ— μš”μ†Œ μ œκ±°ν•˜κΈ°

  1. κ°€μž₯ μž‘μ€ μš”μ†ŒλŠ” 항상 this.heap[1]에 μœ„μΉ˜ν•œλ‹€. 이λ₯Ό value에 ν• λ‹Ήν•œλ‹€.

  2. κ°€μ • λ¨Όμ €ν•΄μ•Ό ν•  과정은 λ°°μ—΄μ˜ this.heap의 λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό rootμœ„μΉ˜μ— λ°°μΉ˜ν•˜λŠ” 것이닀.

  3. 루트만 μžˆλŠ” 상황

    • μš”μ†Œμ˜ 이동 없이 λ°”λ‘œ valueλ₯Ό λ°˜ν™˜ν•œλ‹€.

  4. μ™Όμͺ½ μžμ‹ ν•˜λ‚˜λ§Œ μžˆλŠ” 상황

    • μ™Όμͺ½ μžμ‹μ˜ κ°’κ³Ό ν˜„μž¬ 인덱슀의 값을 λΉ„κ΅ν•˜μ—¬ μ™Όμͺ½ μžμ‹μ˜ 값이 더 μž‘μœΌλ©΄ 두 개의 값을 μ„œλ‘œ λ°”κΎΌλ‹€.

  5. μ™Όμͺ½ μžμ‹κ³Ό 였λ₯Έμͺ½ μžμ‹μ΄ λͺ¨λ‘ μžˆλŠ” 경우

    • μ•„λž˜μ˜ λ°˜λ³΅λ¬Έμ„ μ‹€ν–‰ν•œλ‹€.

  6. μ™Όμͺ½ μžμ‹κ³Ό 였λ₯Έμͺ½ μžμ‹μ˜ κ°’ 쀑 ν•˜λ‚˜λΌλ„ ν˜„μž¬ 인덱슀의 κ°’ 보닀 μž‘μœΌλ©΄ λ°˜λ³΅λ¬Έμ„ 계속 μ‹€ν–‰λœλ‹€. 즉, λΆ€λͺ¨μ˜ 값이 μžμ‹λ“€μ˜ κ°’ 보닀 μž‘μ•„μ Έμ•Ό λ°˜λ³΅λ¬Έμ€ μ’…λ£Œλœλ‹€.

  7. μ™Όμͺ½ μžμ‹κ³Ό 였λ₯Έμͺ½ μžμ‹μ˜ 값을 λΉ„κ΅ν•˜μ—¬ 더 μž‘μ€ 값을 κ°€μ§€λŠ” 인덱슀λ₯Ό min_index에 ν• λ‹Ήν•œλ‹€. μ΄λ•Œ 였λ₯Έμͺ½ μžμ‹μ˜ 값이 μ—†λ‹€λ©΄ 비ꡐ 값은 항상 falseκ°€ λ˜λ―€λ‘œ 이점을 μœ μ˜ν•΄μ•Ό ν•œλ‹€.

  8. λΆ€λͺ¨μ˜ κ°’κ³Ό μžμ‹μ˜ κ°’(더 μž‘μ€)을 λΉ„κ΅ν•˜μ—¬ λΆ€λͺ¨μ˜ κ°’ 보닀 μžμ‹μ˜ 값이 더 μž‘μœΌλ©΄ 두 개의 값을 μ„œλ‘œ λ°”κΎΌλ‹€.

  9. λ‹€μŒ 비ꡐλ₯Ό μœ„ν•΄ 각각의 값듀을 λ°”κΎΌλ‹€.


6. Conclusion

이번 νž™μ˜ μš”μ†Œλ₯Ό μ œκ±°ν•˜λŠ” 과정을 μ •λ¦¬ν•˜λ©΄μ„œ ν•΄λ‹Ή μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•΄ 트리의 μš”μ†Œλ₯Ό μ‚­μ œν•˜λŠ” 것도 κ°€λŠ₯ν•˜μ§€ μ•Šμ„κΉŒλΌλŠ” 생각을 ν•˜μ˜€λ‹€. μ§€κΈˆκΉŒμ§€ 봀던 자료ꡬ쑰 쀑 κ°€μž₯ λ©”μ„œλ“œκ°€ κΈΈμ—ˆλ˜ 것 κ°™λ‹€. 특히 μš”μ†Œμ˜ μ‚­μ œκ°€ κΈΈμ—ˆλŠ”λ° μ‹ κΈ°ν•œ 것은 λ°°μ—΄, μ—°κ²° 리슀트λ₯Ό μ‚¬μš©ν•˜μ—¬ μš°μ„  μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 것보닀 νž™μœΌλ‘œ κ΅¬ν˜„ν•˜λŠ” 것이 μ‹œκ°„ λ³΅μž‘λ„ μΈ‘λ©΄μ—μ„œ 효율적인 면을 λ³΄μΈλ‹€λŠ” 것이닀. μ½”λ“œμ˜ 양은 μ€‘μš”ν•˜μ§€ μ•Šκ³  μ–Όλ§ˆλ‚˜ 효율적으둜 μš”μ†Œλ₯Ό μΆ”κ°€, μ‚­μ œν•˜λŠ” 데에 μžˆλ‹€λŠ” 것을 κΉ¨λ‹«κ²Œ λ˜μ—ˆλ‹€. κ³Όμ—° 이런 νž™ μžλ£Œκ΅¬μ‘°κ°€ μ½”λ”© ν…ŒμŠ€νŠΈ λ¬Έμ œμ—μ„œ μ–΄λ–»κ²Œ 적용이 λ˜μ—ˆλŠ”μ§€ κΆκΈˆν•˜λ‹€.


μ°Έκ³ 

[자료ꡬ쑰] νž™(heap)μ΄λž€ [자료ꡬ쑰] μš°μ„ μˆœμœ„ 큐와 νž™ (Priority Queue & Heap) [자료ꡬ쑰] JS둜 κ΅¬ν˜„ν•˜λŠ” HEAP


πŸ“… 2022-09-12

Last updated