Priority Queue의 분명한 대답 외에, 프로그래밍 모험에서 힙이 언제 유용할까요?
답변:
가장 큰 (또는 가장 작은) 항목에 대한 빠른 액세스가 필요할 때마다 사용하십시오. 해당 항목은 항상 배열의 첫 번째 요소이거나 트리의 루트에 있기 때문입니다.
그러나 배열의 나머지 부분은 부분적으로 정렬되지 않은 상태로 유지됩니다. 따라서 즉시 액세스는 가장 큰 (가장 작은) 항목에만 가능합니다. 삽입이 빠르기 때문에 들어오는 이벤트 또는 데이터를 처리하고 항상 가장 빠르고 가장 큰 데이터에 액세스 할 수있는 좋은 방법입니다.
우선 순위 대기열, 스케줄러 (가장 초기 항목이 필요한 경우) 등에 유용합니다.
힙은 상위 노드의 값이 하위 노드의 값보다 큰 트리입니다.
힙을 깊이에 따라 선형 순서로 저장된 이진 트리로 생각하면 루트 노드가 먼저 (그런 다음 해당 노드의 하위가 다음으로 해당 노드의 하위가 다음)됩니다. 그러면 인덱스 N에있는 노드의 자식은 2N + 1과 2N + 2에 있습니다. 이 속성을 사용하면 인덱스별로 빠르게 액세스 할 수 있습니다. 그리고 힙은 노드를 스와핑하여 조작되기 때문에 내부 정렬이 가능합니다.
힙은 최소값 또는 최대 값에 빠르게 액세스 할 수있는 구조 입니다.
하지만 왜 그걸 원 하겠어요? 추가시 모든 항목을 확인 하여 가장 작은 지 또는 가장 큰지 확인할 수 있습니다. 이렇게하면 항상 일정한 시간에 가장 작거나 가장 큰 것을 갖게됩니다 O(1)
.
대답은 힙을 사용하면 가장 작은 또는 가장 큰 것을 가져오고 NEXT 가장 작은 또는 가장 큰 것을 빠르게 알 수 있기 때문 입니다. 이것이 우선 순위 대기열이라고하는 이유입니다.
나이에 따라 환자가 진료를받는 병원이 있다고 가정 해 보겠습니다. 가장 오래된 사람이 대기열에 언제 들어 갔는지에 관계없이 항상 먼저 참석합니다.
가장 오래된 것을 추적 할 수는 없습니다. 그 / 그녀를 빼 내면 다음으로 가장 오래된 것을 알 수 없기 때문입니다. 이 병원 문제를 해결하기 위해 max heap 을 구현합니다 . 이 힙은 정의에 따라 부분적으로 정렬됩니다. 즉, 환자를 나이별로 분류 할 수는 없지만 가장 오래된 환자가 항상 맨 위에 있다는 것을 알고 있으므로 환자를 일정한 시간에 꺼내고 O(1)
로그 시간에 힙 균형을 다시 조정할 수 있습니다 O(log N)
.
일련의 정수가 있고 median
. 중앙값은 정렬 된 배열의 중간에있는 숫자입니다.
예:
[1, 2, 5, 7, 23, 27, 31]
위의 경우 7
더 작은 숫자를 포함하는 배열 [1, 2, 5]
이 더 큰 숫자를 포함하는 배열 과 크기가 같기 때문에은 중앙값 입니다 [23, 27, 31]
. 일반적으로 배열에 홀수 개의 요소가있는 경우 중앙값은 중간에있는 두 요소의 산술 평균입니다 (예 :) (5 + 7)/2
.
이제 중앙값을 어떻게 추적합니까? 2 개의 힙을 가짐 으로써 현재 중앙값보다 작은 숫자를 포함하는 최소 힙과 현재 중앙값보다 큰 숫자를 포함하는 최대 힙. 이제 이러한 힙이 항상 균형을 이루는 경우 2 개의 힙에는 동일한 수의 요소가 포함되거나 하나는 다른 힙보다 1 개 더 많은 요소를 포함합니다.
시퀀스에 새 요소를 추가 할 때 숫자가 현재 중앙값보다 작 으면 최소 힙에 추가하고, 그렇지 않으면 최대 힙에 추가합니다. 힙이 (하나의 힙이 더 다른 것보다 1 개 이상의 요소가) 불균형이 있다면 이제, 당신은 당기 가장 큰 힙에서 요소 및 추가 작은에. 이제 균형이 잡혔습니다.