06장. 트리 정리
- ch23. 우선운위 큐와 힙
23. 우선운위 큐와 힙
23.1 도입
우선순위 큐
에서는 가장 먼저 입력된 자료가 가장 먼저 꺼내지는 것이 아니라, 우선순위가 가장 높은 자료가 가장 먼저 꺼내진다.균형 잡힌 이진 검색 트리
를 사용해서 우선순위 큐를 구현할 수 있다.- 하지만 이는 소 잡는 칼로 닭을 잡는 것과 같다.
- 휠씬 단순한 구조로도 구현할 수 있다.
힙(heap)
이라는 이진 트리 자료구조로 우선순위 큐를 구현 할 수 있다.- 여기서는 최대 힙이라 가정
- 힙은 대부분의 프로그래밍 언어의 표준 라이브러리에 구현되어 있다.
23.2 힙의 정의와 구현
힙의 대소 관계 규칙: 부모 노드가 가진 원소는 항상 자식 노드가 가진 원소 이상이다. (최대 힙의 경우)
- 가장 중요하고 기본적인 규칙
- 이진 검색 트리와 달리 부모 자식 관계에만 적용
- 왼쪽, 오른쪽 자식이 갖는 원소의 크기는 제한하지 않는다.
힙의 모양 규칙: 이진 검색 트리에서도 문제가 되었던, 트리가 기울어지는 일을 막음
마지막 레벨을 제외한 모든 레벨에 노드가 꽉 차 있어야 한다.
마지막 레벨에 노드가 있을 때는 항상 가장 왼쪽 부터 순서대로 채워져 있어야 한다.
힙의 높이: O(logN)
23.2.1 배열을 이용한 힙의 구현
힙이 요구하는 엄격한 모양 규칙은 구현할 때는 장점이다.
트리에 포함된 노드의 개수만 알면 트리 전체의 구조를 알 수 있기 때문이다.
동적 배열은 힙에 들어 있는 원소들을 맨 윗 레벨 부터, 왼쪽에서 오른쪽 순서대로 저장한다.
A[i]
에 대응되는 노드의 왼쪽 자손은A[2*i+1]
에 대응A[i]
에 대응되는 노드의 오른쪽 자손은A[2*i+2]
에 대응A[i]
에 대응되는 노드의 부모는A[(i-1) / 2 ]
에 대응 (나눗셈 결과는 내림)
23.2.2 새 원소의 삽입(push)
- 힙에서 새 원소를 삽입(push) 할때는 간단한 방법은 대소 관계 규칙 대신 모양 규칙을 먼저 만족시키는 것이다.
- 모양 규칙에 의해 새 노드는 항상 heap배열 에 맨 끝에 추가된다.
- 마직막에 추가한 새 원소를 자신의 부모와 비교
- 비교 후, 작다면 두 원소의 위치를 바꾼다.
- 새 원소가 더 크거나 같은 원소를 가진 부모를 만나거나, 루트에 도달할 때까지 이를 반복한다.
- push(삽입) 의 시간복잡도: 트리의 높이인 O(logN)
23.2.3 최대 원소 꺼내기(pop)
- 배열을 이용한, 최대 힙에서 최대 원소를 찾는 것은 첫 원소를 확인하면 된다. 매우 간단
- 문제는, 최대 원소를 힙에서 꺼내는 것(삭제, pop) 이다.
- 삭제에서도, 삽입과 같이 간단한 방법은 대소 관계 규칙 대신 모양 규칙을 먼저 만족시키는 것이다.
- 힙의 마지막에 있는 리프 노드를 삭제
- 마지막 노드에 있던 원소는 루트로 덮어 씌움
- 두 자식 노드가 가진 원소 중 더 큰 원소를 선택해 루트가 갖고 있는 원소와 맞바꿈.
- 이 작업을 트리의 바닥에 도달하거나, 두 자손이 모두 자기 자신 이하의 우너소를 갖고 있을 때 까지 반복
- pop(삭제) 의 시간복잡도: 트리의 높이인 O(logN)
23.2.4 다른 연산들
힙을 만드는 연산(heapify)
- N개의 원소를 텅 빈 힙에 순서대로 삽입해야 할 때 쓸 수 있다.
- 원소들을 길이가 N인 배열에 저장한 뒤, heapify 연산을 수행하면, O(N)만에 힙으로 만들어 준다.
- push( O(logN) ) 연산을 N번 호출하는, O(NlogN)에 비해 빠르지만,
- 어차피, N개의 원소를 다시 꺼내는 데만도 O(NlogN) 시간이 걸리고, 이것을 프로그램의 수행 시간을 지배해 버리기 때문에 큰 의미는 없다.
힙 정렬(Heapsort)
힙에서 원소들을 꺼낼 때, 항상 정렬된 순서대로 반환된다는 점을 이용
배열을 힙으로 만든 뒤, 모든 원소들을 꺼내서 반환 순서대로 배열하면 정렬 결과가 된다.
이때 힙에서 원소를 하나 꺼내면, 힙을 담은 배열의 맨 뒤쪽이 한 칸 비게 되므로,
- 최대 원소를 여기에 옮기면 추가 메모리를 사용하지 않고 정렬 가능
최악의 경우에도 O(NlogN) 의 시간복잡도, 병합 정렬과 달리 추가적인 메모리 요구하지 않음
Reference
- 프로그래밍 대회에서 배우는 알고리즘 문제 해결 전략 (구종만, 인사이트)
- https://www.algospot.com/