힙 정렬(Heap Sort)

heapsort.gif

최대 힙(Max Heap)혹은 최소 힙(Min Heap)을 구성하여 정렬하는 방식이다

  1. 입력으로 들어오는 배열로 힙(Heap) 트리를 만든다
  2. 내림차순 정렬의 경우 최대 힙 트리를, 오름차순 정렬의 경우 최소 힙 트리를 구성한다
  3. 힙 트리로 구한 최댓값 혹은 최솟값에 해당하는 root를 빼내서 배열에 할당한다
  4. 하나씩 빼낸 root 노드 자리에는 힙트리 가장 뒤에 있는 원소를 넣는다

힙 정렬은 여러 개의 값 중에서 최댓값이나 최솟값을 빠르게 찾기 위해 사용된다

시간복잡도

최선, 평균, 최악 모두 **O(NlogN)**이다

특징

코드

class Heap {
  constructor() {
    this.heap = [];
  }

  getLeftChild = (parent) => {
    return parent * 2 + 1;
  };

  getRightChild = (parent) => {
    return parent * 2 + 2;
  };

  getParent = (child) => {
    return Math.floor((child - 1) / 2);
  };

  insert = (key, value) => {
    const node = { key, value };
    this.heap.push(node);
    this.heapifyUp();
  };

  remove = () => {
    const count = this.heap.length;
    const root = this.heap[0];

    if (count <= 0) return;

    if (count === 1) {
      this.heap = [];
    } else {
      this.heap[0] = this.heap.pop();
      this.heapifyDown();
    }

    return root;
  };

  heapifyUp = () => {
    let index = this.heap.length - 1;
    const insertedNode = this.heap[index];

    while (index > 0) {
      const parent = this.getParent(index);

      if (this.heap[parent].key > insertedNode.key) {
        this.heap[index] = this.heap[parent];
        index = parent;
      } else {
        break;
      }
    }

    this.heap[index] = insertedNode;
  };

  heapifyDown = () => {
    let index = 0;
    const count = this.heap.length;
    const root = this.heap[index];

    while (this.getLeftChild(index) < count) {
      const leftChild = this.getLeftChild(index);
      const rightChild = this.getRightChild(index);

      let minChild;

      if (
        rightChild < count &&
        this.heap[rightChild].key < this.heap[leftChild].key
      ) {
        minChild = rightChild;
      } else {
        minChild = leftChild;
      }

      if (this.heap[minChild].key <= root.key) {
        this.heap[index] = this.heap[minChild];
        index = minChild;
      } else {
        break;
      }
    }

    this.heap[index] = root;
  };
}

function heapSort(arr) {
  const heap = new Heap();

  for (const element of arr) {
    heap.insert(element);
  }

  const sorted = [];

  while (heap.heap.length) {
    const { key } = heap.remove();
    sorted.push(key);
  }

  return sorted;
}