[자료구조] Heap

LMH·2023년 2월 13일
0

이번 포스팅에서는 Heap에 대해서 정리하겠습니다.

Heap은 이진 트리 구조를 가지며 루트가 최대 값을 가지는 경우 최대 이진힙이라 부르고 최소 값을 가지는 경우 최소 이진힙이라 부릅니다. 이진 티르는 배열로 나타낼 수 있는데 배열에서 i번째 인덱스의 요소를 하나 선택했을 때, 그 자식 요소는 2i+1 번째 인덱스(left)의 요소와 2i+2 번째 인덱스의 요소(right)입니다.

이러한 규칙을 이용하면 빠른 시간 내에 데이터를 탐색할 수 있으며 요소를 추가하거나 제거할 때 O(logN) 시간 복잡도를 가집니다. 아래의 코드는 최대 이진힙을 구현한 것 입니다.

class Heap {
  constructor() {
    this.values = [];  // 배열을 value값으로 가집니다.
  }
  // 새로운 값을 추가합니다.
  insert(value) {
    this.values.push(value); 
    this.bubleup();  
  }
  // 추가한 값의 부모 요소와 비교하여 큰 경우 위치를 바꿉니다.
  bubleup() {
    let idx = this.values.length - 1;
    const element = this.values[idx]; // 추가한 마지막 요소
    while (idx > 0) {
      const parentIdx = Math.floor((idx - 1) / 2);
      const parent = this.values[[parentIdx]];

      if (element < parent) break;
      this.values[parentIdx] = element;
      this.values[idx] = parent;
      idx = parentIdx;
    }
  }
  // 가장 큰 값(root)의 value를 꺼내고 마지막 인덱스의 요소를 root로 이동 시 킵니다. 
  extractMax() {
    const max = this.values[0];
    const end = this.values.pop();

    this.values[0] = end;
    this.sinkDown();

    return max;
  }
  // root와 자식들을 비교해서 자식 중 가장 큰 요소와 자리를 바꿉니다.
  sinkDown() {
    let idx = 0;
    const length = this.values.length;
    const element = this.values[0];
    while (true) {
      let leftChildIdx = 2 * idx + 1;
      let rightChildIdx = 2 * idx + 2;
      let swap = null;
      let leftChild, rightChild;

      if (rightChildIdx > length) return;
      if (leftChildIdx < length) {
        leftChild = this.values[leftChildIdx];
        if (leftChild > element) {
          swap = leftChildIdx;
        }
      }
      if (rightChildIdx < length) {
        rightChild = this.values[rightChildIdx];
        if (
          (swap === null && rightChild > element) ||
          (swap !== null && rightChild > leftChild)
        ) {
          swap = rightChildIdx;
        }
        if (swap === null) break;
        this.values[idx] = this.values[swap];
        this.values[swap] = element;
        idx = swap;
      }
    }
  }
}
profile
새로운 것을 기록하고 복습하는 공간입니다.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN