class Heap {
    data: number[] 
    constructor(data:number[] = []) {
        this.data = data;
        this.heapify();  
    }
    size():number {
        return this.data.length;  
    }
    
    heapify():void {
        
        if(this.size() < 2) return;
        
        for(let i = 1; i < this.size(); i ++ ) {
            this.bubbleUp(i); 
        }
    }
    
    offer(val) {
        this.data.push(val);
        this.bubbleUp(this.size() - 1);
    }
    
    poll():number | null {
        if(!this.size()) return null;
        const res = this.data[0];  
        this.data[0] = this.data.pop() as number; 
        this.bubbleDown(0);  
        return res; 
    }
    
    swap(i:number, j:number):void {
        if(i === j ) return;
        [this.data[i], this.data[j]] = [this.data[j], this.data[i]]
    }
    
    bubbleUp(index:number):void {
        
        while(index > 0) {
            let parentIndex = Math.floor((index - 1)/2); 
            
            
            if (this.data[index] > this.data[parentIndex]) break;  
            this.swap(index, parentIndex);  
            index = parentIndex; 
        }
    }
    
    
    bubbleDown(index:number):void {
        let lastIndex = this.size() - 1;  
        while(index < lastIndex) {   
            let leftIndex  = index * 2 + 1;  
            let rightIndex = index * 2 + 2;  
            let findIndex = index;  
            
            if(this.data[leftIndex] < this.data[findIndex]) {
                findIndex = leftIndex;
            }
            if(this.data[rightIndex] < this.data[findIndex]) {
                findIndex = rightIndex;
            }
            
            if(index === findIndex) break;
            this.swap(index,findIndex);  
            index = findIndex;  
        }
    }
}
const arr = [2,3,4,5,6,7,1]
const heap = new Heap(arr);