알고리즘/자료구조

heap구현, heapq사용법

씩씩한 IT블로그 2020. 6. 16. 23:06
반응형

heap의종류 2가지

최대힙 : 부모노드가 자식노드보다 크거나 같음(root node에 최댓값)

최소힙: 부모노드가 자식노드보다 작거나 같음(root node에 최솟값)

< (최소)힙 알고리즘 >

* 직접 구현한 힙

# unsorted : heap으로 만들고자하는 리스트
# index : 아래로 내려가며 heap을 만들기 시작하는 노드 (해당 index의 자식노드들은 모두 heapify된다) 
def heapify(unsorted, index, heap_size):
    smallist = index
    left_index = 2 * index + 1
    right_index = 2 * index + 2
    if left_index < heap_size and unsorted[left_index] < unsorted[smallist]:
        smallist = left_index
    if right_index < heap_size and unsorted[right_index] < unsorted[smallist]:
        smallist = right_index
    if smallist != index:
        unsorted[smallist], unsorted[index] = unsorted[index], unsorted[smallist]
        heapify(unsorted, smallist, heap_size)

왼쪽 자식노드 -> 오른쪽 자식노드 순서대로 비교하여 (부모,왼쪽자식,오른쪽자식) 중 가장 작은 노드의 값을 구함. 이때 변화가 없으면 재귀를 종료하고, 변화가 있으면 변화된 자식노드로 내려가서 다시 재귀 시작.

파이썬 기본 라이브러리의 힙을 이용할땐 import heapq

* heapify (heapq.heapify(L) : 리스트 L을 heapfiy)

heap으로 구성된 tree는 리스트로 나타낼 수 있다.

 

* 삽입 (heapq.heappush(L,num) : 리스트 L에 num 삽입후 heapify)

힙에 삽입을 할때는 노드의 맨끝에 삽입을 한 뒤 삽입된 노드의 부모노드로 부터 아래에서 위(오른쪽에서 왼쪽, 밑에서 위) 로 heapify.

 

* 제거 (heapq.heappop(L) : 힙정렬된 리스트L의 가장 윗 노드 반환 및 제거 후 heapify)

힙을 제거할 떄는 제거한 자리에 맨끝 노드를 넣고 제거한위치에서 아래로 heapify(L,제거한index,len) 한번만 해주면 된다.

모듈은 최소힙만 구현되어 있으며 만약 최대힙을 구현하고 싶을땐 -를 붙이고 push한다음, pop할때 -를 한번더 붙이거나, push할때 [-num,num]와 같이 넣고, pop할때 1을 pop하는 방식으로 구현.

참고 : https://ratsgo.github.io/data%20structure&algorithm/2017/09/27/heapsort/

반응형