Heap

νž™(heap)은 μ΅œλŒ“κ°’ 및 μ΅œμ†Ÿκ°’μ„ μ°Ύμ•„λ‚΄λŠ” 연산을 λΉ λ₯΄κ²Œ ν•˜κΈ° μœ„ν•΄ κ³ μ•ˆλœ μ™„μ „μ΄μ§„νŠΈλ¦¬(Complete binary tree)λ₯Ό 기본으둜 ν•œ 자료ꡬ쑰(tree-based structure)이닀. (μœ„ν‚€λ°±κ³Ό )

μ‘μš©

  1. Graph Algorithm : Dijkstra, Prim's Minimum Spanning Tree(ν”„λ¦Ό μ΅œμ†Œ μ‹ μž₯ 트리)

그리고 λ‹€μ–‘ν•œ 문제λ₯Ό ν‘ΈλŠ”λ°μ—μ„œ μ‚¬μš©λœλ‹€.

κ·œμΉ™

μ΅œμ†Œ νž™(min heap)

λΆ€λͺ¨λ…Έλ“œμ˜ 킀값이 μžμ‹λ…Έλ“œμ˜ 킀값보닀 항상 μž‘κ±°λ‚˜ κ°™λ‹€. key(λΆ€λͺ¨λ…Έλ“œ) < key(μžμ‹λ…Έλ“œ)

μ΅œλŒ€ νž™(max heap)

λΆ€λͺ¨λ…Έλ“œμ˜ 킀값이 μžμ‹λ…Έλ“œμ˜ 킀값보닀 항상 ν¬κ±°λ‚˜ κ°™λ‹€. key(λΆ€λͺ¨λ…Έλ“œ) > key(μžμ‹λ…Έλ“œ)

λ”°λΌμ„œ λ£¨νŠΈλ…Έλ“œμ—λŠ” 항상 κ°€μž₯ 큰 κ°’μ΄λ‚˜ κ°€μž₯ μž‘μ€ 값이 μ €μž₯λ˜μ–΄ μžˆκΈ°λ•Œλ¬Έμ— μ΅œλŒ€κ°’ λ˜λŠ” μ΅œμ†Ÿκ°’μ„ O(1)λ§Œμ— 찾을 수 μžˆλ‹€. μ—¬κΈ°μ„œ 킀값은 μ˜€λ‘œμ§€ λΆ€λͺ¨ μžμ‹λ…Έλ“œκ°„μ—λ§Œ μ„±λ¦½ν•œλ‹€.

Height/Depth

n개의 λ…Έλ“œλ₯Ό κ°€μ§€κ³  μžˆλŠ” heap의 λ†’μ΄λŠ” O(logn)이닀. νž™μ€ μ™„μ „μ΄μ§„νŠΈλ¦¬μ΄λ―€λ‘œ λ…Έλ“œμ˜ 개수둜 κΉŠμ΄μ™€ 높이λ₯Ό 계산할 수 μžˆλ‹€.

λ§ˆμ§€λ§‰ level을 μ œμ™Έν•˜κ³ λŠ” 각 레벨 i에 2^i개의 λ…Έλ“œκ°€ μ‘΄μž¬ν•œλ‹€.

κ΅¬ν˜„

λ°°μ—΄

νž™μ€ μ™„μ „μ΄μ§„νŠΈλ¦¬μ΄λ―€λ‘œ 각 λ…Έλ“œμ— 번호λ₯Ό 뢙일 수 μžˆλ‹€. 배열은 μ™„μ „μ΄μ§„νŠΈλ¦¬λ₯Ό ν‘œν˜„ν•˜κΈ°μ— 맀우 νš¨μœ¨μ μ΄λ‹€.

λ°°μ—΄λ‘œ ν‘œν˜„ν•¨μœΌλ‘œμ¨ λΆ€λͺ¨λ…Έλ“œμ™€ μžμ‹λ…Έλ“œλ₯Ό μ°ΎκΈ°κ°€ μ‰¬μ›Œμ§„λ‹€.

  • μ™Όμͺ½ μžμ‹λ…Έλ“œ 인덱슀 : 2*(λΆ€λͺ¨λ…Έλ“œ 인덱슀)

  • 였λ₯Έμͺ½ μžμ‹λ…Έλ“œ 2*(λΆ€λͺ¨λ…Έλ“œ 인덱슀)+1

  • λ…Έλ“œ x의 λΆ€λͺ¨ λ…Έλ“œ μΈλ±μŠ€λŠ” (μžμ‹λ…Έλ“œ 인덱슀)/2둜 μ•Œ 수 μžˆλ‹€.

μ£Όμ˜μ‚¬ν•­ indexλŠ” 1λΆ€ν„° μ‹œμž‘!ν•œλ‹€λŠ” 점을 μ£Όμ˜ν•΄μ•Όν•œλ‹€.

μ‚½μž…(upheap)

  1. κ°€μž₯ 끝의 μžλ¦¬μ— λ…Έλ“œλ₯Ό μ‚½μž…ν•œλ‹€.

  2. κ·Έ λ…Έλ“œμ™€ λΆ€λͺ¨ λ…Έλ“œλ₯Ό μ„œλ‘œ λΉ„κ΅ν•œλ‹€.

  3. κ·œμΉ™(μ΅œμ†Œνž™, μ΅œλŒ€νž™)에 맞으면 κ·ΈλŒ€λ‘œ 두고, κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ λΆ€λͺ¨μ™€ κ΅ν™˜ν•œλ‹€.

  4. κ·œμΉ™μ— λ§žμ„ λ•ŒκΉŒμ§€ 1~3번 과정을 λ°˜λ³΅ν•œλ‹€.

μ‹œκ°„λ³΅μž‘λ„

  • O(logn)

μ‚­μ œ(downheap)

μ΅œλŒ“κ°’ ν˜Ήμ€ μ΅œμ†Ÿκ°’μ΄ μ €μž₯된 루트 λ…Έλ“œλ§Œ μ œκ±°ν•  수 μžˆλ‹€.

  1. 루트 λ…Έλ“œλ₯Ό μ œκ±°ν•œλ‹€.

  2. 루트 μžλ¦¬μ— κ°€μž₯ λ§ˆμ§€λ§‰ λ…Έλ“œλ₯Ό μ‚½μž…ν•œλ‹€.

  3. μ˜¬λΌκ°„ λ…Έλ“œμ™€ 그의 μžμ‹ λ…Έλ“œ(λ“€)와 λΉ„κ΅ν•œλ‹€.

  4. 쑰건에 λ§Œμ‘±ν•˜λ©΄ κ·ΈλŒ€λ‘œ 두고, κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μžμ‹κ³Ό κ΅ν™˜ν•œλ‹€.

  5. μ΅œλŒ€ νž™ 1. λΆ€λͺ¨λ³΄λ‹€ 더 큰 μžμ‹μ΄ μ—†μœΌλ©΄ κ΅ν™˜ν•˜μ§€ μ•Šκ³  끝낸닀. 2. λΆ€λͺ¨λ³΄λ‹€ 더 큰 μžμ‹μ΄ ν•˜λ‚˜λ§Œ 있으면 κ·Έ μžμ‹ν•˜κ³  κ΅ν™˜ν•˜λ©΄ λœλ‹€. 3. λΆ€λͺ¨λ³΄λ‹€ 더 큰 μžμ‹μ΄ λ‘˜ 있으면 μžμ‹λ“€ 쀑 큰 κ°’κ³Ό κ΅ν™˜ν•œλ‹€.

  6. μ΅œμ†Œ νž™ 1. λΆ€λͺ¨λ³΄λ‹€ 더 μž‘μ€ μžμ‹μ΄ μ—†μœΌλ©΄ κ΅ν™˜ν•˜μ§€ μ•Šκ³  끝낸닀. 2. λΆ€λͺ¨λ³΄λ‹€ 더 μž‘μ€ μžμ‹μ΄ ν•˜λ‚˜λ§Œ 있으면 κ·Έ μžμ‹ν•˜κ³  κ΅ν™˜ν•˜λ©΄ λœλ‹€. 3. λΆ€λͺ¨λ³΄λ‹€ 더 μž‘μ€ μžμ‹μ΄ λ‘˜ 있으면 μžμ‹λ“€ 쀑 μž‘μ€ κ°’κ³Ό κ΅ν™˜ν•œλ‹€.

  7. 쑰건을 λ§Œμ‘±ν•  λ•ŒκΉŒμ§€ 4의 과정을 λ°˜λ³΅ν•œλ‹€.

μ‹œκ°„λ³΅μž‘λ„

  • O(logn)

κ΅¬ν˜„

μ΅œμ†Œνž™

#include <stdio.h>
#define MAX 1000000

typedef struct{
    int heap[MAX];
    int hsize;
}Heap;

void init(Heap * h){
    h->hsize=0;
}

void insert(Heap * h, int key){
    int p; //ν˜„μž¬ μœ„μΉ˜ μ €μž₯

    // λ§ˆμ§€λ§‰ μœ„μΉ˜μ— μΆ”κ°€
    h->heap[++(h->hsize)]=key;

    // μœ„μΉ˜ μ‘°μ •
    p=h->hsize;
    while((h->heap[p/2])>key){
        h->heap[p] = h->heap[p/2];
        p/=2;
    }
    h->heap[p]=key;
}

int delete(Heap * h){
    int min,last,child,i;

    //λ£¨νŠΈλ…Έλ“œκ°’μ΄ μ΅œμ†Œ
    min = h->heap[1];
    last = h->heap[(h->hsize)--];

    for(i=1; i*2<=h->hsize; i=child){
        child = i*2;
        if(child!=h->hsize && h->heap[child+1]<h->heap[child])child++;
        if(last>h->heap[child])h->heap[i]=h->heap[child];
        else break;
    }
    h->heap[i]=last;
    return min;
}


int main(int argc, const char * argv[]) {

    Heap heap;
    int min;
    init(&heap);
    insert(&heap, 10);
    insert(&heap, 5);
    insert(&heap, 30);

    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }
    min = delete(&heap);
    printf("\n%d \n",min);
    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }
    min = delete(&heap);
    printf("\n%d \n",min);
    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }


    return 0;
}

μ΅œλŒ€νž™

#include <stdio.h>
#define MAX 100

typedef struct{
    int heap[MAX];
    int hsize;
}Heap;

void init(Heap * h){
    h->hsize=0;
}

void insert_max(Heap * h, int key){
    int p; //ν˜„μž¬ μœ„μΉ˜ μ €μž₯

    p=++(h->hsize);
    // λ§ˆμ§€λ§‰ μœ„μΉ˜μ— μΆ”κ°€
    h->heap[p]=key;


    // μœ„μΉ˜ μ‘°μ •
    while((h->heap[p/2])<key){
        if(p==1)break;
        h->heap[p] = h->heap[p/2];
        p/=2;
    }
    h->heap[p]=key;
}
int delete_max(Heap * h){
    int max,last,child,i;

    //λ£¨νŠΈλ…Έλ“œκ°’μ΄ μ΅œμ†Œ
    max = h->heap[1];
    last = h->heap[(h->hsize)--];

    for(i=1; i*2<=h->hsize; i=child){
        child = i*2;
        if(child!=h->hsize && h->heap[child+1]>h->heap[child])child++;
        if(last<h->heap[child])h->heap[i]=h->heap[child];
        else break;
    }
    h->heap[i]=last;
    return max;
}


int main(int argc, const char * argv[]) {

    Heap heap;
    int max;
    init(&heap);
    insert_max(&heap, 10);
    insert_max(&heap, 5);
    insert_max(&heap, 30);

    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }
    max = delete_max(&heap);
    printf("\n%d \n",max);
    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }
    max = delete_max(&heap);
    printf("\n%d \n",max);
    for(int i=1;i<=heap.hsize;i++){
        printf("%d ",heap.heap[i]);
    }


    return 0;
}

Last updated

Was this helpful?