본문 바로가기
프론트엔드

자바스크립트로 구현한 Max Heap

by 느바 2022. 3. 12.
반응형

자바스크립트로 구현한 Max Heap

 

(heap)은

최댓값 및 최솟값을 찾아내는 연산을 빠르게 하기 위해 고안된

완전이진트리(complete binary tree)를 기본으로 한 자료구조(tree-based structure)다.

 

힙에는 두가지 종류가 있으며,

부모노드의 키값이 자식노드의 키값보다 항상 큰 힙을 '최대 힙',

부모노드의 키값이 자식노드의 키값보다 항상 작은 힙을 '최소 힙'이라고 부른다.

max heap

출처 : https://ko.wikipedia.org/wiki/%ED%9E%99_(%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0) 

 

힙 (자료 구조) - 위키백과, 우리 모두의 백과사전

1부터 100까지의 정수를 저장한 최대 힙의 예시. 모든 부모노드들이 그 자식노드들보다 큰 값을 가진다. 힙(heap)은 최댓값 및 최솟값을 찾아내는 연산을 빠르게 하기 위해 고안된 완전이진트리(com

ko.wikipedia.org

 

 

자바스크립트로 구현한 Max Heap

class MaxHeap{
    constructor(){
        this.arr = [];
    }
    parent(index){
        return Math.floor((index-1)/2);
    }
    leftChild(index){
        return (index*2)+1;
    }
    rightChild(index){
        return (index*2)+2;
    }
    isLeaf(index){ // if index is a node that has no children, return true
        return (
            index >= Math.floor(this.arr.length / 2) && index <= (this.arr.length - 1)
        )
    }
    swap(index1, index2){
        [this.arr[index2], this.arr[index1]] = [this.arr[index1], this.arr[index2]];
    }
    add(element){
        this.arr.push(element); // add element to the end of heap
        this.heapifyUp(this.arr.length -1);
    }
    heapifyUp(index){
        let currentIndex = index;
        let parentIndex = this.parent(currentIndex);
        while(currentIndex > 0 && this.arr[currentIndex] > this.arr[parentIndex]){
            this.swap(currentIndex, parentIndex);
            currentIndex = parentIndex;
            parentIndex = this.parent(parentIndex);
        }
    }
    extractMax() { // remove and return max element
        if (this.arr.length < 1) return 'heap is empty';
    
        // get max and last element
        const max = this.arr[0];
        const end = this.arr.pop();
        // reassign first element to the last element
        this.arr[0] = end;
        // heapify down until element is back in its correct position
        this.heapifyDown(0);
    
        // return the max
        return max;
    }
    heapifyDown(index) {
        // if the node at index has children
        if (!this.isLeaf(index)) {
    
            // get indices of children
            let leftChildIndex = this.leftChild(index),
                rightChildIndex = this.rightChild(index),
    
                // start out largest index at parent index
                largestIndex = index;
    
            // if the left child > parent
            if (this.arr[leftChildIndex] > this.arr[largestIndex]) {
                // reassign largest index to left child index
                largestIndex = leftChildIndex;
            }
    
            // if the right child > element at largest index (either parent or left child)
            if (this.arr[rightChildIndex] >= this.arr[largestIndex]) {
                // reassign largest index to right child index
                largestIndex = rightChildIndex;
            }
    
            // if the largest index is not the parent index
            if (largestIndex !== index) {
                // swap
                this.swap(index, largestIndex);
                // recursively move down the heap
                this.heapifyDown(largestIndex);
            }
        }
    }
    buildHeap(array) {
        this.arr = array;
        // since leaves start at floor(nodes / 2) index, we work from the leaves up the heap
        for(let i = Math.floor(this.arr.length / 2); i >= 0; i--){
            this.heapifyDown(i);
        }
    }
    peek() {
        return this.arr[0];
    }
    print() {
        let i = 0;
        while (!this.isLeaf(i)) {
            console.log("PARENT:", this.arr[i]);
            console.log("LEFT CHILD:", this.arr[this.leftChild(i)]);
            console.log("RIGHT CHILD:", this.arr[this.rightChild(i)]);
            i++;
        }      
    }
}

 

반응형

'프론트엔드' 카테고리의 다른 글

3D 속성  (0) 2022.08.18
자바스크립트로 구현한 Tree, BFS, DFS  (0) 2022.03.12
자바스크립트로 구현한 hash table  (0) 2022.03.11
단일연결리스트로 구현한 Stack, Queue  (0) 2022.03.10
user story  (0) 2022.03.02