JAVA/백준
백준 1927번: 최소 힙
부리와 깃털
2024. 5. 23. 11:22
728x90
반응형
https://www.acmicpc.net/problem/1927
배열에 가장 작은 수를 출력하고 삭제하는 연산과 배열에 자연수 x를 추가하는 최소 힙을 구현하는 문제이다.
힙은 데이터의 입출력마다 그 크기를 동적으로 변화시켜주는 ArrayList로 구현한다.
데이터의 입력은 일단 마지막에 추가를 하고, 그 뒤에 추가한 노드가 부모노드를 가지고 있다면
추가한 노드가 홀수인지, 짝수인지 확인하고 그것에 맞춰 부모노드랑 크기를 비교해서
더 작다면 부모노드와 위치를 바꿔준다.
그렇게 새로 추가한 노드가 더이상 위치를 바꾸지 않는 지점 혹은 index 0이 될 때 까지 반복해준다.
데이터의 출력은 가장 작은 수를 출력하게 하므로 index 0을 출력한다.
그 뒤에 index 0에 마지막 노드를 넣고, 마지막 노드는 삭제해서 크기를 조절한다.
그 뒤로 index 0부터 시작해서 좌우 자식 노드들과 비교를 하면서 제자리를 찾도록 한다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
import java.util.ArrayList;
public class Main {
static ArrayList<Integer> heap = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
for (int n = 0; n < N; n++) {
int x = Integer.parseInt(br.readLine());
if (x == 0) {
if ( heap.isEmpty() ) sb.append("0\n");
else sb.append(del() + "\n");
}
else {
insert(x);
}
}
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write(sb + "");
bw.flush();
bw.close();
}
static int swap(int a, int b) {
int temp = heap.get(a);
heap.set(a, heap.get(b));
heap.set(b, temp);
return a;
}
static void insert(int x) {
heap.add(x);
int addNode = heap.size() - 1;
while(addNode != 0) {
if ( (addNode-1)%2 == 0 ) { //홀수노드
if ( heap.get( (addNode-1)/2 ) > x )
addNode = swap((addNode-1)/2, addNode);
else break;
}
else { //짝수노드
if ( heap.get( (addNode-2)/2 ) > x )
addNode = swap((addNode-2)/2, addNode);
else break;
}
}
}
static int del() {
int root = heap.get(0);
heap.set(0, heap.get(heap.size() - 1));
heap.remove(heap.size() - 1);
int node = 0;
while (2*node + 1 < heap.size()) {
int leftNode = 2*node + 1;
int rightNode = 2*node + 2;
if (rightNode < heap.size())
leftNode = (heap.get(leftNode) < heap.get(rightNode)) ? leftNode : rightNode;
if (heap.get(node) > heap.get(leftNode)) {
node = swap(leftNode, node);
}
else break;
}
return root;
}
}
반응형