아래 특성을 가진 이진 트리
i) 구조적 성질 : 완전이진트리
ii) 힙 성질 : 모든 노드의 값은 자식 노드의 값보다 크거나 같다(최대힙)
또는 자식 노드의 값보다 작거나 같다(최소힙)
i가 특정 노드의 인덱스일때
예시)
알고리즘
def getLeftChild(index, n):
left_child = 2 * index + 1
if left_child < n:
return left_child
return None
def getRightChild(index, n):
right_child = 2 * index + 2
if right_child < n:
return right_child
return None
def rebuildHeap(heap, root, n):
current = root
value = heap[root]
left_child = getLeftChild(current, n)
while (left_child):
right_child = getRightChild(current)
larger_child = left_child
if (right_child and heap[right_child] > heap[left_child]):
larger_child = right_child
if value < heap[larger_child]:
heap[current] = heap[larger_child]
current = larger_child
else:
heap[current] = value
break
힙을 이용한 정렬 방법
리프 노드가 아닌 노드를 찾아 상향식으로 rebuildHeap
알고리즘
n = len(heap)
# (n-1)-1//2 = 마지막 노드의 부모
for i in range((n-1)-1//2, -1, -1):
rebuildHeap(heap, i, n)
다음 과정을 반복해 정렬한다
1) 루트 노드와 마지막 노드를 교환한다
2) 힙 크기를 1 줄인다. rebuildHeap 한다
3) 루트 노드가 유일한 노드가 될 때까지 반복한다
최대힙의 루트는 최대 값이므로 오름차순으로 정렬된다
알고리즘
heap_size = n
root = 0
for last in range(n-1, 0, -1):
tmp = heap[root]
heap[root] = heap[last]
heap[last] = tmp
heap_size -= 1
rebuildHeap(heap, root, heap_size)
def heapSort(heap):
# 1단계
n = len(heap)
last_parent = ((n-1)-1)//2
for i in range(last_parent, -1, -1):
rebuildHeap(heap, i, n)
# 2단계
heap_size = n
root = 0
for last in range(n-1, 0, -1):
tmp = heap[root]
heap[root] = heap[last]
heap[last] = tmp
heap_size -= 1
rebuildHeap(heap, root, heap_size)
힙을 사용하는 대표적인 예
알고리즘
def insert(heap, key):
heap_size += 1
i = heap_size-1
while i > 0 and heap[Parent(i)] < key:
heap[i] = heap[Parent(i)]
i = Parent(i)
heap[i] = key
알고리즘
def deleteMax(heap):
max = heap[0]
heap[0] = heap[last]
heap_size -= 1
rebuildHeap(heap, 0, heap_size)
return max