typedef struct element {
    int key;
} element;

typedef struct HeapType {
    element heap[MAX_ELEMENT];
    int heap_size;
} HeapType;
void heap_sort(element a[], int n) {
    int i;
    HeapType h;

    init(&h);

    for (i = 0; i < n; i++) {
        insert_max_heap(&h, a[i]);
    }

    for (i = (n - 1); i >= 0; i--) {
        a[i] = delete_max_heap(&h);
    }
}
void insert_max_heap(HeapType* h, element item) {
    int i;
    i = ++(h->heap_size); // 힙 크기 증가

    /* 트리를 거슬러 올라가면서 부모 노드와 비교하는 과정
        i가 루트 노트(index = 1)가 아니고, 삽입할 값(item)이 i의 부모 노드(index = i/2)보다 크면
        i번째 노드와 부모 노드를 교환하고, 한 레벨 위로 */
    while ((i != 1) && (item.key > h->heap[i / 2].key)) {
        //
        h->heap[i] = h->heap[i / 2];
        i /= 2;
    }

    // 새로운 노드 삽입
    h->heap[i] = item; 
}

element delete_max_heap(HeapType* h) {
    int parent, child;
    element item, temp;

    item = h->heap[1]; // 루트 노드 값을 반환하기 위해 item에 할당
    temp = h->heap[(h->heap_size)--]; // 마지막 노드를 temp에 할당하고 힙 크기 하나 감소
    parent = 1;
    child = 2;

    /* 현재 노드의 자식 노드 중 더 큰 자식 노드를 찾기
       (루트 노드의 왼쪽 자식 노드(index: 2)부터 비교 시작) */
    while (child <= h->heap_size) {
        if ((child < h->heap_size) && ((h->heap[child].key) < h->heap[child + 1].key)) {
            child++;
        }

        // 더 큰 자식 노드보다 마지막 노드가 크면, while문 중지
        if (temp.key >= h->heap[child].key) {
            break;
        }

        // 더 큰 자식 노드보다 마지막 노드가 작으면, 부모 노드와 더 큰 자식 노드를 교환
        h->heap[parent] = h->heap[child];

        // 한 단계 아래로 이동
        parent = child;
        child *= 2;
    }

    // 마지막 노드를 재구성한 위치에 삽입 후 최댓값(root) 반환
    h->heap[parent] = temp;
    return item;
}