heap - changicho/algorithm-training GitHub Wiki

heap

heap

๊ฐ’๋“ค์˜ ๋Œ€์†Œ ๊ด€๊ณ„๋Š” ๋ถ€๋ชจ์™€ ์ž์‹ ๋…ธ๋“œ ๊ฐ„์—๋งŒ ์กด์žฌํ•œ๋‹ค.

์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” log(n) ์ด๋‹ค.

heap ์ž๋ฃŒ๊ตฌ์กฐ

long long heap[100002];
int heap_size = 0;

์ตœ์†Œ heap

heap ์‚ญ์ œ ์—ฐ์‚ฐ

๋ฃจํŠธ ๋…ธ๋“œ์˜ ๊ฐ’์„ ์‚ญ์ œํ•˜๊ณ , ํž™์˜ ๋งจ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ ๊ฐ’์„ ๋ฃจํŠธ์— ๋„ฃ์€ ๋’ค ๊ฐฑ์‹ ํ•œ๋‹ค.

void heap_delete() {
  int current, left, right;

  heap[1] = heap[heap_size];
  heap[heap_size] = 0;
  heap_size -= 1;

  if (heap_size == 0) {
    return;
  }

  current = 1;
  while (true) {
    left = current * 2;
    right = current * 2 + 1;

    if (left > heap_size) {
      break;
    }

    // if it has only left node
    if (right > heap_size) {
      if (heap[left] < heap[current]) {   // ๋ณ€๊ฒฝ์ 
        swap(heap[left], heap[current]);
        current = left;
        continue;
      }
    }
    // if it has two node
    else {
      if (heap[left] <= heap[right]) {   // ๋ณ€๊ฒฝ์ 
        if (heap[left] < heap[current]) {   // ๋ณ€๊ฒฝ์ 
          swap(heap[left], heap[current]);
          current = left;
          continue;
        }
      }
      else {
        if (heap[right] < heap[current]) {   // ๋ณ€๊ฒฝ์ 
          swap(heap[right], heap[current]);
          current = right;
          continue;
        }
      }
    }

    if (current == left / 2) {
      break;
    }
  }

  return;
}

heap push ์—ฐ์‚ฐ (์ตœ์†Œ ํž™)

ํž™์˜ ๋งจ ๋งˆ์ง€๋ง‰์— ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋„ฃ๊ณ , ๋ถ€๋ชจ๋…ธ๋“œ์™€ ๋น„๊ตํ•˜๋ฉฐ ๊ฐฑ์‹ ํ•œ๋‹ค.

void heap_push(int input) {
  heap_size += 1;
  heap[heap_size] = input;

  int current = heap_size, parent;

  while (true) {
    if (current == 1) break;

    parent = current / 2;

    if (heap[current] < heap[parent]) {   // ๋ณ€๊ฒฝ์ 
      swap(heap[parent], heap[current]);
    }
    else {
      break;
    }
    current = parent;
  }
}

์ตœ๋Œ€ ํž™

์œ„ ์‹์—์„œ ์ฃผ์„์ฒ˜๋ฆฌํ•œ ๋ถ€๋ถ„์˜ ๋“ฑํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ตœ๋Œ€ ํž™์ด ๋œ๋‹ค.

์šฐ์„ ์ˆœ์œ„ ํ

์šฐ์„ ์ˆœ์œ„ ํ์˜ ๊ฒฝ์šฐ heap์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

priority_queue<int> pq; // ์šฐ์„ ์ˆœ์œ„ ํ ์„ ์–ธ

cin >> input;

switch(input){
  case 0:{
    if (pq.empty()) {   // queue๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ 0 ์ถœ๋ ฅ
      cout << "0\n";
    } else {
      // ๊ฐ€์žฅ ์œ„์— ๋“ค์–ด๊ฐ€์žˆ๋Š” ๊ฐ’์„ ์ถœ๋ ฅ
      cout << pq.top() << "\n";
      pq.pop();
    }
  }
  case 1:{
    pq.push(x); // ์ž…๋ ฅํ•œ ์ˆซ์ž queue์— ์‚ฝ์ž…
  }
}

struct๋ฅผ ์ด์šฉํ•œ priority queue

STL queue ์˜ priority_queue๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๋‘๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

๊ตฌ์กฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ operator๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

๋ฐฉ๋ฒ• 1 : compare ๊ตฌ์กฐ์ฒด ์‚ฌ์šฉ

struct Data {
  int abs, value;
};
struct compare {
  bool operator()(Data a, Data b) {
    if (a.abs != b.abs) {
      return a.abs > b.abs;
    }
    return a.value > b.value;
  }
};
priority_queue<Data, vector<Data>, compare> pq;

๋ฐฉ๋ฒ• 2 : operator๋ฅผ ์˜ค๋ฒ„๋กœ๋”ฉ

struct Data {
  int abs, value;
};
bool operator<(Data a, Data b) {
  if (a.abs != b.abs) {
    return a.abs > b.abs;
  }
  return a.value > b.value;
}
priority_queue<Data> pq;

๋ฐฉ๋ฒ• 3 : ๊ตฌ์กฐ์ฒด์— ์ง์ ‘ operator ์„ ์–ธ

struct Data {
  int abs, value;
  bool operator<(const Data &b) const {
    if (abs != b.abs) {
      return abs > b.abs;
    }
    return value > b.value;
  }
};
priority_queue<Data> pq;
โš ๏ธ **GitHub.com Fallback** โš ๏ธ