Search

Heap (우선순위 큐)

힙은 최댓값 및 최솟값을 찾아내는 연산을 빠르게 하기 위해 고안된 완전이진트리를 기본으로 한 자료구조로서 다음과 같은 힙 속성을 만족한다. A가 B의 부모노드 이면, A의 키값과 B의 키값 사이에는 대소관계가 성립한다. 위키백과
우선순위 큐를 위해 만들어진 자료구조다
우선순위 큐:
큐에 우선순위를 도입한 자료구조. 우선순위가 높은 데이터부터 삭제된다. (먼저 나간다)
배열, 연결리스트, 힙으로 구현 가능. 힙이 가장 효율적
최댓값/최솟값을 빠르게 찾아내도록 만들어졌다.
힙 트리는 중복 값을 허용한다

종류

최대 힙(max heap)
부모노드 키 값 ≥ 자식노드 키값
최소 힙(min heap)
부모노드 키 값 ≤ 자식노드 키값

구현

완전이진트리이기 때문에 각 노드에 인덱스를 부여해 배열로 구현이 가능하다.
편의를 위해 0인덱스는 사용하지 않는다.
특정 위치의 노드 인덱스는 새로운 노드가 추가되더라도 변하지 않는다. ex) 루트노드의 오른쪽 노드 번호는 항상 3
왼쪽 자식의 인덱스 = 부모 인덱스 * 2
오른쪽 자식의 인덱스 = 부모 인덱스 * 2 + 1
부모의 인덱스 = 자식의 인덱스 / 2 (몫)

heap의 삽입(Upheap 연산)

1.
요소를 가장 하위 레벨의 최대한 왼쪽으로 삽입 ( 배열에선 가장 마지막)
2.
부모값과 비교해 더 작은 경우 위치 변경 (위치 변경이 없을 때 까지 반복)
시간복잡도 : O(log(N))O(\log(N))

heap의 삭제(Downheap 연산)

시간복잡도 O(log(N))O(\log(N))

구현

# 최소힙 class BinaryHeap(): def __init__(self): self.items = [None] def __len__(self): return len(self.items) - 1 def insert(self, k): self.items.append(k) self._percolate_up() def _percolate_up(self): i = len(self) parent = i//2 while parent >= 0: # 부모와 비교하여 더 작으면 둘을 교환 if self.items[i] < self.items[parent]: self.items[parent], self.items[i] = self.items[i], self.items[parent] i = parent parent = i // 2 def extract(self): extracted = self.items[1] self.items[1] = self.items[len(self)] self.items.pop() self._percolate_down(1) return extracted def _percolate_down(self, idx): left = idx * 2 right = idx * 2 + 1 smallest = idx if left <= len(self) and self.items[left] < self.items[smallest]: # 왼 노드로 지정된 index가 힙 요소 길이를 벗어나지 않고 현재 smallest의 값보다 작을경우 smallest= left # smallest는 left(왼노드의 인덱스)로 교환 if right <= len(self) and self.items[right] < self.items[smallest]: smallest = right # right에 대해 동일하게 if smallest != idx: # 자식노드들과의 비교가 끝났을 때 smallest가 입력된 idx와 다르다면 둘을 교체 self.items[idx], self.items[smallest] = self.items[smallest], self.items[idx] self._percolate_down(smallest) # 교체 하였으므로 smallest위치에는 원래 idx에 있던 값이 존재함. 이에 대해서 다시 재귀 호출. 점점 내려가는 과정을 이렇게 구현
Python
복사