힙 데이터구조는 우선순위 큐를 구현하는데 유용합니다. 우선순위 큐는 다음과 같은 연산을 효율적으로 지원합니다.
Insert()
Maximum() / Minimum():
Extract-Max() / Extract-Min():
ChangeKey(x, new_key):
-요소 x의 키 값을 새로운 값 new_key의 값으로 변경합니다.
정렬된 연결리스트를 사용한 우선순위 큐에 대해 알아보겠습니다.
Insert
Extract Max
리스트가 정렬되어 있으므로, 가장 첫번째 원소를 가져오면 됩니다.
시간복잡도는 이 됩니다.
리스트가 정렬되어있다면, 추출할 때 시간이 적게걸리고, insert할때는 시간이 오래걸립니다.
정렬되지 않은 연결리스트를 사용한 우선순위 큐에 대해 알아보겠습니다.
Insert
Extract Max
리스트 전체를 탐색하여 최댓값을 찾아야 합니다.
시간복잡도는 이 됩니다.
리스트가 정렬되어있지 않다면, 추출할 때 시간이 오래걸리고, insert할때는 시간이 적게걸립니다.
많은 추출연산이 필요한 경우 정렬된 리스트가 더 나은 성능을 보이고, 삽입이 빈번한 경우 정렬되지않은 리스트가 더 유리할 수 있습니다.'
INSERT와 EXTRACT-MAX 의 시간복잡도는 모두 으로 어느 한쪽에 치우치지 않고 양쪽 모두 좋은 성능입니다.
EXTRACT-MAX: 앞에서 설명한 최대힙에서 최댓값을 추출하는 방법과 동일합니다.
INSERT: 삽입은 Insertion-Sort와 유사합니다.
HEAPIFY와 비슷하게 O(log n) 노드를 트래버스하지만 HEAP-INSERT 비교와 할당이 적습니다.
왜냐하면, HEAPIFY는 부모를 두 자식과 비교하지만, HEAP-INSERT는 하나의 부모와만 비교하기 떄문입니다.
HEAP-INSERT(A, key, n)
n ← n + 1
i ← n
while i > 1 and A[⌊i/2⌋] < key do
A[i] ← A[⌊i/2⌋]
i ← ⌊i/2⌋
A[i] ← key
예를 통해 Heap-Insert 를 알아봅시다.
1. 새로운 요소를 배열의 끝에 추가합니다
2. 새로운 요소 '15'를 부모 노드 A[5] = 7과 비교합니다.
3. 15 > 7이므로, 15를 A[5]로 이동시킵니다.
4. 다시 15의 부모 노드 A[2] = 14와 비교합니다.
5. 15 > 14이므로, 15를 A[2]로 이동시킵니다.
6. 이제 15의 부모 노드 A[1] = 16과 비교합니다.
7. 15 < 16이므로, 15는 A[2]에 위치하게 됩니다.
예시를 통해 알아봅시다
HEAP-INCREASE-KEY(A, 9, 15)