ํž™(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. ํž™์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ

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

this.heap์„ ๋ฐฐ์—ด๋กœ ์ด์šฉํ•˜์—ฌ ์„ ์–ธ์„ ํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋Š” null๋กœ ์ €์žฅํ•œ๋‹ค.


5-2. ํž™์— ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ

class Heap {
  // ...
  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);
    }
  }
}

์ตœ์†Œ ํž™์€ ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์ œ์ผ ์ž‘์•„์•ผ ํ•œ๋‹ค. ํ˜„์žฌ ๋…ธ๋“œ์™€ ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ๊ฐ’์„ ๋น„๊ตํ•˜์—ฌ ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ๊ฐ’์ด ํฌ๋‹ค๋ฉด ๊ทธ ๋‘˜์„ ์„œ๋กœ ๋ฐ”๊พธ์–ด ์ค€๋‹ค.

๋งŒ์•ฝ ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค๊ฐ€ 1์ด๊ฑฐ๋‚˜ ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ๋ถ€๋ชจ ๋…ธ๋“œ ๋ณด๋‹ค ๊ฐ’์ด ์ž‘๋‹ค๋ฉด ๋ฐ˜๋ณต๋ฌธ ๋” ์ด์ƒ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.


5-3. ํž™์— ์š”์†Œ ์ œ๊ฑฐํ•˜๊ธฐ

class Heap {
  // ...
  pop() {
    // 1.
    const value = this.heap[1];

    // 2.
    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;

    // 3. ๋ฃจํŠธ๋งŒ ์žˆ๋Š” ์ƒํ™ฉ
    if (!this.heap[left_index]) return value;
    // 4. ์™ผ์ชฝ ์ž์‹ ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ์ƒํ™ฉ
    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;
    }

    // 5. ์™ผ์ชฝ ์ž์‹๊ณผ ์˜ค๋ฅธ์ชฝ ์ž์‹์ด ๋ชจ๋‘ ์žˆ๋Š” ๊ฒฝ์šฐ
    while (
      // 6.
      this.heap[left_index] < this.heap[cur_index] ||
      this.heap[right_index] < this.heap[cur_index]
    ) {
      // 7.
      let min_index =
        this.heap[left_index] > this.heap[right_index]
          ? right_index
          : left_index;
      // 8.
      [this.heap[min_index], this.heap[cur_index]] = [
        this.heap[cur_index],
        this.heap[min_index],
      ];
      // 9.
      cur_index = min_index;
      left_index = cur_index * 2;
      right_index = cur_index * 2 + 1;
    }
    return value;
  }
}
  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