ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ #11279 최대 힙
    BOJ 2021. 1. 29. 16:05

    문제

    널리 잘 알려진 자료구조 중 최대 힙이 있다. 최대 힙을 이용하여 다음과 같은 연산을 지원하는 프로그램을 작성하시오.

    1. 배열에 자연수 x를 넣는다.
    2. 배열에서 가장 큰 값을 출력하고, 그 값을 배열에서 제거한다.

    프로그램은 처음에 비어있는 배열에서 시작하게 된다.

    입력

    첫째 줄에 연산의 개수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 큰 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 자연수는 231보다 작다.

    출력

    입력에서 0이 주어진 회수만큼 답을 출력한다. 만약 배열이 비어 있는 경우인데 가장 큰 값을 출력하라고 한 경우에는 0을 출력하면 된다.

     


    소스코드(C언어)

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    
    void reheapup(int n);
    int extractMax();
    void reheapDown(int n);
    
    int arr[1000000] = { 0 };
    int idx = 0;
    int isheap = 0; //heap이 만들어진 상태인지 체크
    
    int main() {
    	int N, tmp;
    	scanf("%d", &N);
    	for (int i = 0; i < N; i++) {
    		scanf("%d", &tmp);
    		if (tmp) {
    			arr[idx++] = tmp;	//0 ~ idx-1까지 element 존재
    			isheap = 0;
    		}
    		else {
    			if (!isheap) { //buildheap
    				for (int i = 1; i < idx; i++) { 
    					reheapup(i);
    				}
    				isheap = 1;
    			}
    			printf("%d\n", extractMax());
    		}
    	}
    
    	return 0;
    }
    
    void reheapup(int n) {
    	if (n > 0) {
    		int parent = (n - 1) / 2;
    
    		if (arr[parent] < arr[n]) {
    			int tmp = arr[n];
    			arr[n] = arr[parent];
    			arr[parent] = tmp;
    
    			reheapup(parent);
    		}
    	}
    }
    
    int extractMax() {
    	if (!idx)
    		return 0;
    
    	int tmp = arr[0];
    	arr[0] = arr[idx - 1];
    	idx--;
    
    	reheapDown(0);
    
    	return tmp;
    }
    
    void reheapDown(int n) {
    	int left = 2 * n + 1;
    	int right = 2 * n + 2;
    	int max = n;
    
    	if (left < idx && arr[left] > arr[n])
    		max = left;
    	if (right < idx && arr[right] > arr[max])
    		max = right;
    
    	if (max != n) {
    		int tmp = arr[n];
    		arr[n] = arr[max];
    		arr[max] = tmp;
    
    		reheapDown(max);
    	}
    }

     

    ※ 주의

    힙을 완전히 새로 만들 때의 시간복잡도 → O(n*logn)

    최댓값을 제거하고 난 후 힙을 재정렬할 때의 시간복잡도  O(logn)

    'BOJ' 카테고리의 다른 글

    BOJ #11286 절댓값 힙  (0) 2021.01.29
    BOJ #1927 최소 힙  (0) 2021.01.29
    BOJ #2751 수 정렬하기 2  (0) 2021.01.29
    BOJ #2750 수 정렬하기  (0) 2021.01.29
    BOJ #15829 Hashing  (0) 2021.01.19

    댓글

Designed by Tistory.