최소 힙
28 August 2019
문제 : https://www.acmicpc.net/problem/1927
이번은 최솟값을 빠르게 뽑는 문제를 풀어보도록 하겠습니다.
#include<stdio.h>
static int heap[300000] = {};
static int size = 0;
void add(int data);
void remove();
int main(void) {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
int val;
scanf("%d", &val);
if (val == 0)
{
remove();
}
else {
add(val);
}
}
return 0;
}
int getParent(int idx) {
return ((idx - 1) / 2);
}
int getLeft(int idx) {
return (idx * 2 + 1);
}
int getRight(int idx) {
return (idx * 2 + 2);
}
void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
void add(int data) {
heap[size] = data;
int idx = size;
while (true)
{
int parentIdx = getParent(idx);
if (heap[idx] < heap[parentIdx])
{
swap(idx, parentIdx);
idx = parentIdx;
}
else {
break;
}
}
size++;
}
void remove() {
if (size == 0)
{
printf("0\n");
return;
}
printf("%d\n", heap[0]);
heap[0] = heap[size - 1];
size--;
int idx = 0;
while (true)
{
int min = idx;
int left = getLeft(idx);
int right = getRight(idx);
if (left < size && heap[left] < heap[min])
{
min = left;
}
if (right < size && heap[right] < heap[min])
{
min = right;
}
if (min == idx)
{
break;
}
else {
swap(idx, min);
idx = min;
}
}
}
간단한 최소 힙 문제입니다.최소 힙을 구현해주고, 0이면 remove, 다른 수일때는 insert를 해주고, 뺄 때마다 해당 값을 출력해주도록 합니다.
insert할 때에는 배열의 가장 마지막에 넣어주고 parent값과 연속적으로 비교하여 현재의 값이 더 작으면 바꿔줍니다.
remove일때는 가장 마지막 값을 가장 앞에 넣어주고, 차례로 child를 돌면서 현재 값보다 가장 작은 값과 바꿔줍니다.
해당 logic대로 최소 힙을 구현하도록 합니다.