완전이진트리의 일종으로 우선순위 큐를 우하여 만들어진 자료구조

최댓값이나 최솟값을 빠르게 찾아내도록 만들어진 구조

 

완전이진트리 - 노드를 삽입할때 왼쪽부터 차례대로 삽입하는 트리

 

최대 힙 최소 힙
부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전이진트리 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전이진트리

완전이진트리는 배열로 구현한다.

필자는 배열이 재할당을 알아서 해주기위해 vector를 사용 

또한 이 코드는 최대 힙으로 구현

#include <iostream>
#include <vector>

using namespace std;

class Heap
{
    int size = 0;
    vector<int> heap; 
public:
    void push(int value) 
    {
        heap.push_back(value);
        sort(size);
        size++;
    }

    void sort(int _size)
    {
        int c = _size;
        int p = (c - 1) / 2;

        while (c > 0 && heap[c] > heap[p])
        {
            swap(c, p);
            c = p;
            p = (c - 1) / 2;
        }
    }

    void swap(int a, int b) {
        int temp = heap[a];
        heap[a] = heap[b];
        heap[b] = temp;
    }

    int pop()
    {
        if (size == 0)
        {
            cout << "비어있습니다." << endl;
            return 0;
        }

        int poll = heap[0];
        heap[0] = heap[--size];
        popsort();

        return poll;
    }

    void popsort()
    {
        int p = 0;
        int c = 1;

        while(c <= size) {
            if(c < size && heap[c] < heap[c + 1])
                c++;
            if(heap[c] <= heap[p]) break;

            swap(c, p);
            p = c;
            c = c * 2 + 1;
        }
    }


    void print()
    {
        for(int i=0; i<heap.size(); i++)
            cout << heap[i] << " ";
        cout << endl;
    }

};

int main()
{
    Heap h;

    h.push(1);
    h.push(10);
    h.push(2);
    h.push(6);
    h.push(3);
    h.push(7);
    h.push(5);
    h.push(6);
    h.push(8);

    h.print();
    cout << "pop: " << h.pop() << endl;
    h.print();
}

 

특정 노드의 배열 인덱스가 current라고 한다면 

 

index가 1부터 시작할때)

부모노드 = current 

좌측자식노드 = current * 2

우측자식노드 = current * 2 + 1

 

 

 

편리성을위해 이진트리 구현할때 보통 index는 1부터 시작하지만 필자는, 위에서 구현한 코드는  0 부터 사용하였다.

index가 0부터 시작할때)

부모노드 = current - 1 

좌측자식노드 = current * 2 + 1 

우측자식노드 = current * 2 + 2

 

 

 

 

힙 삽입 과정 O(log N)

1. 인덱스 순으로 가장 마지막 위치에 삽입

 

2. 부모 노드 6 < 삽입노드 8 이므로 서로 교환

 

3. 부모노드 6 < 삽입노드 8 이므도 서로 교환

 

4. 부모노드 10 > 삽입노드 8 이므로 더 이상 교환하지않는다.

 

 

 

 

힙 삭제 과정 O(log N)

1. 힙에서 삭제는 루트노드가 삭제된다 

 

2. 삭제된 루트노드에 힙의 마지막 노드를 가져온다.

 

3. 가져온 루트노드와 자식노드중 더 큰 자식노드와 교환한다.

 

4. c 가 size보다 커지거나 (마지막 레벨이거나) 자식노드들 보다 클때까지 반복한다.

'자료구조' 카테고리의 다른 글

단일 연결 리스트  (0) 2022.05.02

+ Recent posts