언제 힙을 사용하고 싶습니까?


92

Priority Queue의 분명한 대답 외에, 프로그래밍 모험에서 힙이 언제 유용할까요?


8
여기에 좋은 답변이 많이 있으므로 "더미가 충분히 크지 않을 때"라고 말하겠습니다.
Don Werve

답변:


121

가장 큰 (또는 가장 작은) 항목에 대한 빠른 액세스가 필요할 때마다 사용하십시오. 해당 항목은 항상 배열의 첫 번째 요소이거나 트리의 루트에 있기 때문입니다.

그러나 배열의 나머지 부분은 부분적으로 정렬되지 않은 상태로 유지됩니다. 따라서 즉시 액세스는 가장 큰 (가장 작은) 항목에만 가능합니다. 삽입이 빠르기 때문에 들어오는 이벤트 또는 데이터를 처리하고 항상 가장 빠르고 가장 큰 데이터에 액세스 할 수있는 좋은 방법입니다.

우선 순위 대기열, 스케줄러 (가장 초기 항목이 필요한 경우) 등에 유용합니다.

힙은 상위 노드의 값이 하위 노드의 값보다 큰 트리입니다.

힙을 깊이에 따라 선형 순서로 저장된 이진 트리로 생각하면 루트 노드가 먼저 (그런 다음 해당 노드의 하위가 다음으로 해당 노드의 하위가 다음)됩니다. 그러면 인덱스 N에있는 노드의 자식은 2N + 1과 2N + 2에 있습니다. 이 속성을 사용하면 인덱스별로 빠르게 액세스 할 수 있습니다. 그리고 힙은 노드를 스와핑하여 조작되기 때문에 내부 정렬이 가능합니다.


3
또한 추가 어레이 할당이 필요하지 않은 편리한 보장 NlogN 정렬 일 수 있습니다.
Overflown

38
인터뷰 질문에 대한 힙을 아는 것도 좋습니다;)
vivekian2

21
@ vivekian2 내가 여기있는 유일한 이유는 인터뷰를해야하기 때문입니다.
byxor 2011

가장 큰 (또는 가장 작은) 항목을 추적하기 위해 보조 스택과 함께 스택 클래스를 사용하지 않는 이유는 무엇입니까? 검색이 O (1)이다
Ridhwaan 샤킬

@RidhwaanShakeel 스택을 사용하면 아이템이 항상 머리 위에 놓이게되는데, 가장 큰 이벤트 (이벤트에 참여한 사람 수 기준)와 같은 아이템의 속성에 따라 아이템의 위치를 ​​결정해야한다면 어떨까요?
SandeepGodara

49

힙은 최소값 또는 최대 값에 빠르게 액세스 할 수있는 구조 입니다.

하지만 왜 그걸 원 하겠어요? 추가시 모든 항목을 확인 하여 가장 작은 지 또는 가장 큰지 확인할 수 있습니다. 이렇게하면 항상 일정한 시간에 가장 작거나 가장 큰 것을 갖게됩니다 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 개 이상의 요소가) 불균형이 있다면 이제, 당신은 당기 가장 큰 힙에서 요소 및 추가 작은에. 이제 균형이 잡혔습니다.


6
더 정교한 예는 놀랍습니다! 언젠가는 이걸 꼭 시도해 볼게요. 그러나 나는 당신의 예에 작은 실수가 있다고 생각합니다. 중간에있는 두 요소를 평균하여 중앙값을 구해야하기 때문입니다. 현재 중앙값보다 큰 숫자를 저장하려면 최소 힙을, 현재 중앙값보다 작은 숫자를 저장하려면 최대 힙을 사용해야한다고 가정합니다. 이렇게하면 중간에있는 두 요소를 일정한 시간에 추출하고 중앙값을 계산할 수 있습니까? 제가 맞습니까?
Calvin Ku

12

힙의 특징은 데이터를 반순으로 유지하는 구조라는 것입니다. 따라서 완전한 질서를 유지하는 비용과 무작위 혼돈을 검색하는 비용 사이의 좋은 절충안입니다. 이 특성은 선택, 정렬 또는 분류와 같은 많은 알고리즘에서 사용됩니다.

힙의 또 다른 유용한 특성은 배열에서 제자리에 만들 수 있다는 것입니다!


3

선택 알고리즘 (최소 또는 최대 찾기)에도 좋습니다.


3

임시 목록을 정렬 할 때 언제든지 힙을 고려해야합니다.


0

가장 작은 요소와 가장 큰 요소에 각각 액세스하려는 경우 minHeap 또는 maxHeap을 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.