이진 최소 힙의 증가 키 및 감소 키


16

이진 힙에 대한 많은 토론에서 일반적으로 감소 키만 최소 힙에 대해 지원되는 작업으로 나열됩니다. 예를 들어 CLR 챕터 6.1 및 이 위키 백과 페이지 입니다. min-heap에 대해 증가 키가 일반적으로 나열되지 않는 이유는 무엇입니까? 자식이 x보다 크지 않을 때까지 증가 된 요소 (x)를 자식의 최소값으로 반복적으로 교환하여 O (높이)에서 그렇게 할 수 있다고 생각합니다.

예 :

IncreaseKey(int pos, int newValue)
{
   heap[pos] = newValue;
   while(left(pos) < heap.Length)
   {
      int smallest = left(pos);
      if(heap[right(pos)] < heap[left(pos)])
         smallest = right(pos);
      if(heap[pos] < heap[smallest])
      { 
         swap(smallest, pos);
         pos= smallest;
      }
      else return;
   }   
}

위의 내용이 맞습니까? 그렇지 않다면 왜? 그렇다면 왜 최소 힙에 대해 키를 올리지 않습니까?


1
모든 대답을 읽은 후에는 Dijkstra 알고리즘에서 역사적으로 min-heap을 처음 사용했을 때 이상한 누락이라고 할 수 있습니다.
maaartinus

3
물론 delete와 insert를 사용하여 항상 증가 키를 구현할 수 있으며 delete 자체는 감소 키 (-∞)와 delete-min으로 구현할 수 있습니다.
davmac

@maaartinus 의견이 정답입니다.
최대

답변:


6

제안하는 알고리즘은 단순히 힙입니다. 그리고 실제로-최소 힙에서 요소의 값을 늘리고 하위 트리를 힙화하면 합법적 최소 힙으로 끝납니다.


그렇다면 CLR 또는 Wikipedia list 증가 키가 지원되는 작업이 아닌 이유는 무엇입니까? 그것은 약간의 힙에서는 가능하지 않다고 생각하는 것이 잘못되었다
GatotPujo

오해의 소지가 있음에 동의하지만 알고리즘에는 실수가 없습니다.
Shaull

5

작업이 나열되지 않은 이유는 특정 데이터 구조를 사용하여 쉽게 구현할 수있는 모든 작업에 관심이있는 것이 아니라 다른 방법으로 수행하기 때문입니다. 일련의 작업이 주어지면 이러한 작업을 구현하는 가장 효율적인 방법 (공간 및 시간)입니다. (그러나 나중에 이것에 더 추가합니다)

이진 힙은 추상 데이터 구조 우선 순위 큐를 구현하여 is_empty, add_element (우선 순위가있는 키), find_min 및 delete_min을 요청합니다. 고급 대기열을 사용하면 키의 우선 순위를 낮추거나 (min_heap) 키를 늘릴 수도 있습니다. 실제로, 당신은 구현을 제공했습니다.

두 가지 말. 배열에서 힙을 효율적으로 생성하는 heapify 함수에서 작업이 사용됩니다. 힙화에서 작업이 반복됩니다 (마지막 키부터 시작).

그리고 가장 중요한 것은 코드가 노드의 위치를 ​​사용한다는 것입니다. 부정 행위중인 순수한 데이터 구조 우선 순위 큐의 경우. 해당 데이터 구조는 키가 주어진 특정 작업을 수행하도록 요청합니다. 따라서 요소의 우선 순위를 줄이거 나 늘리려면 먼저 요소를 찾아야합니다. 그것이 그것이 목록에없는 주된 이유라고 생각합니다.


1
설명 주셔서 감사합니다. 그러나 CLR 감소 키에서도 매개 변수로서 노드로서의 위치가 있습니다.
GatotPujo

네 말이 맞아 CLRS의 6.5 절의 우선 순위 큐 정의에서이 비대칭성에 대한 이유를 찾을 수 없습니다. 참고이 장의 응용 프로그램 인 Heapsort에서는 증가 키가 사용되지 않습니다. 증가와 감소 사이의 비대칭은 Dijkstra 알고리즘과 같은 데이터 구조가 사용되는 방식과 만 관련이있는 것 같습니다. 선택된 일부 노드가 (최소 힙 사용) 더 긴급 해지고 힙에서 '위로'이동할 수 있습니다.
Hendrik Jan

0

가장 먼저 고려해야 할 것은 지원되는 작업이란 무엇입니까?

"특정 고정 키로 값 삽입"(예 : 정수 영역에서 가져온 키의 경우 키 = 3으로 삽입)이 최소 힙에 대해 지원되는 작업에 해당합니까?

더 일반적인 지원 작업으로 해당 작업을 간단하게 구현할 수 있기 때문입니다. 마찬가지로 기존의 insert조작으로 2 개의 요소를 한 번에 삽입 할 수 있습니다 .

한편, insert구현 세부 사항을 노출시키는 것 외에는 조작을 정의 할 수 없습니다. Wikipedia 페이지에 나열된 작업과 거의 동일합니다.heapify 시퀀스는에 의해 구현 될 수 있습니다 insert.

다시 말해, 유형에 제공된 기본 오퍼레이션이 있으며, 이는 수행 세부 사항에 밀접하게 바인드되며, 해당 규칙을 준수하지 않는 다른 오퍼레이션이 있으므로 조합으로 구현 될 수 있습니다. 표준적인 것들.

이러한 정의를 염두에두고 성능 저하없이 지원되는 다른 작업으로 증가 키를 구현할 수 있다고 생각하십니까? 그렇다면 위의 정의에 의해 지원되는 작업이 아니므로 그렇지 않을 수 있습니다.

내가 아는 한, 내가 제공하는 지원되는 운영의 정의는 내 주장이다. 그것은 공식적이지 않으므로 토론의 대상이됩니다 (그러나 그것은 나에게 분명해 보이지만). 그러나 누군가가 데이터 유형에 대해 지원되는 작업을 명확하고 명확하게 정의하거나 최소한 내보다 더 나은 용어로 정의하는 소스를 제공 할 수 있다면 기쁠 것입니다 (CLR에 해당 정의가 있습니까? ).

두 번째 요점은 우선 순위 큐 (이진 힙의 비율)를 정의하는 방법에 관한 것입니다. 입니다increase_key 적절한 사용하는 데이터 형에 필요한 동작, 즉?

보시다시피 내 각도는 정의에 관한 것입니다. 나는 당신의 질문에 대한 답을 제공하지 않고 단지 몇 가지 조언을 제공하므로 개선을 환영합니다.


1
가장 최근에 사용한 객체를 기준으로 객체의 우선 순위 대기열을 유지하려는 경우 (예 : 가장 최근에 사용한 객체를 쉽게 삭제할 수 있도록) 샘플 사용 사례가 될 수 있습니다. 마지막 액세스 날짜가있는 최소 힙을 키로 사용할 수 있습니다. 객체에 액세스하면 키를 늘려야합니다.
GatotPujo

아주 좋은 지적입니다. 내 관점은 약간 제한적입니다. 실제로 @HendrikJan 답변은 매우 좋은 설명을 제공합니다.
didierc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.