힙은 데이터에서 최대값과 최소값을 빠르게 찾기 위해 고안된 완전 이진 트리(Complete Binary Tree)이다
항상 큰 값이 상위 레벨에 있고 작은 값이 하위 레벨에 있도록 하는 자료구조입니다.
다시 말하면 부모 노드의 값이 자식 노드의 값보다 항상 커야 합니다.
그러면 가장 큰 값은 모든 자식보다 커야 하기 때문에 가장 위로 가겠죠!
따라서 최대의 값들을 빠르게 구할 수 있게 되는 것입니다.
최대 힙의 정 반대이다
항상 작은 값이 상위 레벨에 있고 큰 값이 하위 레벨에 있도록 하는 자료구조
그러면 가장 작은 값은 모든 자식보다 작아야 하기 때문에, 가장 위의 값이 최솟값이 된다
원소를 추가하거나 삭제할 때도 힙의 규칙을 성립 해야한다
루트 노드만 추출/삭제 가능
스택과 같이 맨 위에 있는 원소만 제거할 수 있고, 다른 위치의 노드를 삭제할 수는 없습니다!
삽입은 원소를 맨 밑에 넣어서 꼭대기까지 비교하면서 올리고,
추출은 작은 값으로 교체된 루트 노드와 가장 큰 자식을 바꿔가며 내립니다.
완전 이진트리의 최대 높이는 O(log_2(N)) 이기에, 반복하는 최대 횟수도 O(log_2(N)) 입니다.
맥스 힙의 원소 추가는 O(log_2(N)) 만큼의 시간 복잡도를 가진다고 분석할 수 있습니다.
파이썬의 내장함수이고
0부터 시작하는 인덱스를 사용한다
heapq.nlargest(n, iterable, key=None)
"""
iterable에 정의된 데이터 집합에서 n개의 가장 큰 요소로 구성된 리스트를 반환합니다
배열이 정렬되어있을 경우, 절반씩 줄여나가면서 탐색하는 기법 (=이분 탐색)
bisect.bisect_left(nums :list , target: int)
##원하는 target 값의 index 하나를 반환한다
예외상황
import bisect
def binary_search_builtin(nums, target):
idx = bisect.bisect_left(nums, target)
# idx == len(nums) 가능하기 떄문.
"""Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e < x, and all e in
a[i:] have e >= x. So if x already appears in the list, a.insert(x) will
insert just before the leftmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""
if idx < len(nums) and nums[idx] == target:
return idx
else:
return -1
## 예외1. 만약 [-1,1,3,3,5]배열에서 3를 찾는다면 첫 번째 3의 index 2 반환
## 예외2. 만약 [-1,1,3,3,5]배열에서 2를 찾는다면 1,3사이까지 찾은 후 3의 index 2 반환
## 예외3. 만약 [-1,1,3,3,5]배열에서 2를 찾는다면 1,3사이까지 찾은 후 3의 index 2 반환
## 예외4. 만약 [-1,1,3,3,5]배열에서 9를 찾는다면 5반환
## 예외5. 만약 [-1,1,3,3,5]배열에서 -2를 찾는다면 -1반환