인프런 커뮤니티 질문&답변

Choi Boo님의 프로필 이미지
Choi Boo

작성한 질문수

비전공자의 전공자 따라잡기 - 자료구조(with JavaScript)

heapify

최소힙의 결과값과 최대힙->최소힙 결과값이 다른게 맞나요?

작성

·

164

0

최소 힙 insert

#reheapUp(index) {
  // index 0은 root

  if (index > 0) {
    // 부모 노드가 root가 아니면 계속 비교
    const parentIndex = Math.floor((index - 1) / 2);

    if (this.arr[index] < this.arr[parentIndex]) {
      // 값 바꾸기
      const temp = this.arr[index];
      this.arr[index] = this.arr[parentIndex];
      this.arr[parentIndex] = temp;
      this.#reheapUp(parentIndex);
    }
  }
}

// O (log n)
insert(value) {
  this.arr.push(value);

  this.#reheapUp(this.arr.length - 1);
}
const heap = new MinHeap();
// insert는 큰 값부터 넣고, root가 8이 되는지 확인
heap.insert(78);
heap.insert(56);
heap.insert(45);
heap.insert(32);
heap.insert(23);
heap.insert(19);
heap.insert(8);
// [8, 32, 19, 78, 45, 56, 23]
heap;

 

최대 힙 insert

#reheapUp(index) {
  // index 0은 root

  if (index > 0) {
    // 부모 노드가 root가 아니면 계속 비교
    const parentIndex = Math.floor((index - 1) / 2);

    if (this.arr[index] > this.arr[parentIndex]) {
      // 값 바꾸기
      const temp = this.arr[index];
      this.arr[index] = this.arr[parentIndex];
      this.arr[parentIndex] = temp;
      this.#reheapUp(parentIndex);
    }
  }
}

// O (log n)
insert(value) {
  this.arr.push(value);

  this.#reheapUp(this.arr.length - 1);
}
const heap = new MaxHeap();
// insert는 작은 값부터 넣고, root가 78이 되는지 확인
heap.insert(8);
heap.insert(19);
heap.insert(23);
heap.insert(32);
heap.insert(45);
heap.insert(56);
heap.insert(78);
// [78, 32, 56, 8, 23, 19, 45]
heap;

 

최대 힙 -> 최소 힙

// 최소 힙 유지 함수
#heapifyMin(index) {
  // 수정, 삭제

  const leftIndex = index * 2 + 1;
  const rightIndex = index * 2 + 2;

  const smallerIndex =
    (this.arr[leftIndex] || 0) < (this.arr[rightIndex] || 0)
      ? leftIndex
      : rightIndex;

  if (this.arr[index] > this.arr[smallerIndex]) {
    // 값 바꾸기
    const temp = this.arr[index];
    this.arr[index] = this.arr[smallerIndex];
    this.arr[smallerIndex] = temp;
    // 재귀적으로 최소 힙 유지
    this.#heapifyMin(smallerIndex);
  }
}

toMinHeap() {
  // O(1/2n)
  for (let i = Math.floor(this.arr.length / 2 - 1); i >= 0; i--) {
    this.#heapifyMin(i);
  }
}
const heap = new MaxHeap();
// insert는 작은 값부터 넣고, root가 78이 되는지 확인
heap.insert(8);
heap.insert(19);
heap.insert(23);
heap.insert(32);
heap.insert(45);
heap.insert(56);
heap.insert(78);
// [78, 32, 56, 8, 23, 19, 45]
heap.toMinHeap();
// [8, 23, 19, 32, 78, 56, 45]
heap;

 

// 최소 힙 insert 결과 값
[8, 32, 19, 78, 45, 56, 23]

// 최대 힙 insert 결과 값
[78, 32, 56, 8, 23, 19, 45]

// 최대 힙 -> 최소 힙 결과 값
[8, 23, 19, 32, 78, 56, 45]

 

최소힙 insert 결과 값과 최대 힙 -> 최소 힙 결과 값은 서로 다른데 최소 힙의 조건은 아래가 크고, 위가 작다. 라고 하셨으니 결과 값은 달라도 최소 힙의 조건이 맞으니 최대 힙 -> 최소 힙 변환 코드가 맞는걸까요?

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

최소 힙과 최대 힙은 각각 힙의 속성을 만족하는 다른 데이터 구조이기 때문에, 인서트 과정에서 원소들이 서로 다른 위치에 배치될 수 있습니다. 제공해주신 코드를 살펴보면, 최소 힙에 원소를 직접 삽입하는 경우와 최대 힙을 먼저 만들고 이를 최소 힙으로 변환하는 경우에 각각의 힙 속성이 유지됩니다.

최소 힙의 경우 작은 값이 상위 노드에 위치하고, 최대 힙에서는 큰 값이 상위 노드에 위치합니다. 각각의 insert 연산은 힙의 속성을 유지하도록 구현되어 있어 순서대로 원소를 삽입할 경우 힙이 올바른 구조를 이루게 됩니다. 하지만 원소를 삽입하는 순서나 방식이 달라질 경우 힙 내부의 원소 배치는 달라질 수 있습니다. 그러나 모든 경우에서 부모 노드가 자식 노드보다 작다는 최소 힙의 조건은 유지되어야 합니다.

질문하신 최대 힙 -> 최소 힙 변환 코드는 최대 힙에 있는 모든 원소들이 최소 힙의 조건을 만족하도록 재구성하는 과정으로, 변환 후에도 모든 부모 노드는 자식 노드보다 작아야 합니다. 따라서 변환 후 결과값이 처음에 최소 힙을 만들 때의 결과값과 다르더라도, 모든 노드가 최소 힙의 조건을 만족한다면 올바른 결과입니다.

최소 힙의 조건인 ‘아래가 크고, 위가 작다’는 속성이 변환된 최소 힙 결과값 [8, 23, 19, 32, 78, 56, 45]에도 잘 적용되고 있기 때문에, 질문자님께서 제공하신 최대 힙 -> 최소 힙 변환 코드는 맞는 것으로 보입니다.

Choi Boo님의 프로필 이미지
Choi Boo

작성한 질문수

질문하기