๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[์ž๋ฃŒ ๊ตฌ์กฐ]์ด์ง„ ํž™ Binary Heap

์ถœ์ฒ˜ 

ChatGPT


์ด์ง„ ํž™ (Binary Heap)์€ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ์˜ ํ•œ ํ˜•ํƒœ๋กœ, ํž™ ํŠน์„ฑ์„ ๋งŒ์กฑํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. ์ด์ง„ ํž™์€ ์ฃผ๋กœ ์ตœ์†Œ ํž™(Min Heap)๊ณผ ์ตœ๋Œ€ ํž™(Max Heap) ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

 

์ตœ์†Œ ํž™ Min Heap

๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ํ•ญ์ƒ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ๋”ฐ๋ผ์„œ ๋ฃจํŠธ ๋…ธ๋“œ์—๋Š” ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์ด ์œ„์น˜ํ•œ๋‹ค.

์ตœ๋Œ€ ํž™ Max Heap

๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ํ•ญ์ƒ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ๋”ฐ๋ผ์„œ ๋ฃจํŠธ ๋…ธ๋“œ์—๋Š” ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ํฐ ๊ฐ’์ด ์œ„์น˜ํ•œ๋‹ค.

 

1. ์ด์ง„ ํž™์˜ ํŠน์„ฑ

์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ Complete Binary Tree

์ด์ง„ ํž™์€ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๋ชจ๋“  ๋ ˆ๋ฒจ์€ ๊ฐ€๋“ ์ฐจ ์žˆ์œผ๋ฉฐ, ๋งˆ์ง€๋ง‰ ๋ ˆ๋ฒจ์€ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ๋…ธ๋“œ๊ฐ€ ์ฑ„์›Œ์ ธ์•ผ ํ•œ๋‹ค.

ํž™ ์†์„ฑ Heap Property

์ตœ๋Œ€ ํž™์—์„œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•˜๊ณ , ์ตœ์†Œ ํž™์—์„œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ€ ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. ์ด ์†์„ฑ์ด ์œ ์ง€๋˜์–ด์•ผ ํž™์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

 

2. ์ด์ง„ ํž™์˜ ์ฃผ์š” ์—ฐ์‚ฐ + 3. ์ด์ง„ ํž™์˜ ๋ฐฐ์—ด ํ‘œํ˜„

Heap์— ๋Œ€ํ•ด ์ž‘์„ฑํ•œ ๊ธ€์˜ ๋‚ด์šฉ(์ฃผ์š” ์—ฐ์‚ฐ๊ณผ ๋ฐฐ์—ด ํ‘œํ˜„)์€ ๋™์ผํ•จ.

 

4. ์ด์ง„ ํž™์˜ ๊ตฌํ˜„ ์˜ˆ์‹œ (์ตœ์†Œ ํž™)

public class MinHeap {
    private int[] heap;
    private int size;
    private int capacity;

    public MinHeap(int capacity) {
        this.capacity = capacity;
        this.size = 0;
        this.heap = new int[capacity];
    }

    // ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค
    private int getParentIndex(int index) { return (index - 1) / 2; }
    
    // ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค
    private int getLeftChildIndex(int index) { return 2 * index + 1; }
    
    // ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ ์ธ๋ฑ์Šค
    private int getRightChildIndex(int index) { return 2 * index + 2; }

    // ์š”์†Œ ์‚ฝ์ž…
    public void insert(int value) {
        if (size == capacity) throw new IllegalStateException("Heap is full");

        heap[size] = value;
        size++;
        heapifyUp(size - 1);  // ์‚ฝ์ž… ํ›„ ํž™ ์—… ์‹คํ–‰
    }

    // ํž™ ์—…(์ƒํ–ฅ์‹ ํž™ ์ •๋ ฌ)
    private void heapifyUp(int index) {
        while (index > 0 && heap[index] < heap[getParentIndex(index)]) {
            swap(index, getParentIndex(index));
            index = getParentIndex(index);
        }
    }

    // ์ตœ์†Ÿ๊ฐ’(๋ฃจํŠธ) ์‚ญ์ œ
    public int removeMin() {
        if (size == 0) throw new IllegalStateException("Heap is empty");

        int min = heap[0];
        heap[0] = heap[size - 1];
        size--;
        heapifyDown(0);  // ์‚ญ์ œ ํ›„ ํž™ ๋‹ค์šด ์‹คํ–‰
        return min;
    }

    // ํž™ ๋‹ค์šด(ํ•˜ํ–ฅ์‹ ํž™ ์ •๋ ฌ)
    private void heapifyDown(int index) {
        int smallest = index;
        int left = getLeftChildIndex(index);
        int right = getRightChildIndex(index);

        if (left < size && heap[left] < heap[smallest]) {
            smallest = left;
        }

        if (right < size && heap[right] < heap[smallest]) {
            smallest = right;
        }

        if (smallest != index) {
            swap(index, smallest);
            heapifyDown(smallest);
        }
    }

    // ๋‘ ์š”์†Œ ๊ตํ™˜
    private void swap(int i, int j) {
        int temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

    // ํž™ ๋‚ด์šฉ ์ถœ๋ ฅ
    public void printHeap() {
        for (int i = 0; i < size; i++) {
            System.out.print(heap[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        MinHeap minHeap = new MinHeap(10);
        minHeap.insert(20);
        minHeap.insert(15);
        minHeap.insert(30);
        minHeap.insert(5);
        minHeap.insert(10);

        minHeap.printHeap();  // ์ถœ๋ ฅ: 5 10 30 20 15

        System.out.println("Min value removed: " + minHeap.removeMin());  // ์ถœ๋ ฅ: 5
        minHeap.printHeap();  // ์ถœ๋ ฅ: 10 15 30 20
    }
}

 

5. ์ด์ง„ ํž™์˜ ์‘์šฉ

1. ์šฐ์„ ์ˆœ์œ„ ํ Priority Queue

์ด์ง„ ํž™์€ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค. ์šฐ์„ ์ˆœ์œ„ ํ๋Š” FIFO ๊ทœ์น™ ๋Œ€์‹ , ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์š”์†Œ๊ฐ€ ๋จผ์ € ์ฒ˜๋ฆฌ๋˜๋Š” ํ๋กœ, ํž™์„ ์ด์šฉํ•˜์—ฌ ๋น ๋ฅด๊ฒŒ ์‚ฝ์ž… ๋ฐ ์‚ญ์ œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”์˜ PriorityQueue๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ด์ง„ ์ตœ์†Œ ํž™์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ๋‹ค.

2. ํž™ ์ •๋ ฌ Heap Sort

ํž™ ์ •๋ ฌ์€ ์ด์ง„ ํž™์„ ์ด์šฉํ•œ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ, ๋ฐฐ์—ด์„ ํž™์œผ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„, ์ตœ๋Œ“๊ฐ’ ๋˜๋Š” ์ตœ์†Ÿ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ์ œ๊ฑฐํ•˜์—ฌ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ๋‹ค. ํž™ ์ •๋ ฌ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n log n)์ด๋ฉฐ, ์ œ์ž๋ฆฌ ์ •๋ ฌ(in-place sorting)์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

3. ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ Dijkstra's Algorithm

์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ, ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ž‘์€ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ์ •์ ์„ ์„ ํƒํ•˜๋Š” ๋ฐ ์ด์ง„ ํž™์ด ์‚ฌ์šฉehls๋‹ค. ์ด์ง„ ํž™์€ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

 

๊ฒฐ๋ก 

์ด์ง„ ํž™(Binary Heap)์€ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ, ์ตœ๋Œ“๊ฐ’ ๋˜๋Š” ์ตœ์†Ÿ๊ฐ’์„ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ณ  ์‚ฝ์ž… ๋ฐ ์‚ญ์ œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค. ์ด์ง„ ํž™์€ ์šฐ์„ ์ˆœ์œ„ ํ, ํž™ ์ •๋ ฌ, ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋“ฑ์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๋ฉฐ, ๊ฐ ์—ฐ์‚ฐ์€ O(log n) ๋˜๋Š” O(n) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค.