package com.hithomelabs.princeton1.module8;

/*
 * * Designing Heap as a wrapper class with static methods that perform sink and swim operations on underlying comparable[] array
 * * Heap does not have any instance variables, instance variables shall be housed by, the implementation using heaps, like priority queues and heap sort
 */

import com.hithomelabs.princeton1.module5.AbstractCustomSorts;

public class Heap{

    /*
    * * Sink Node T with to it's appropriate place in a Heap of size N, if it's children exist and are greater
    */
    public static <T> void sink(T[] arr, int root, int N){
        // *  Check if at least one child exists
        while(2 * root <= N){
            int j = 2 * root;
        // *  Check if the right child exists and is larger than the left child, if yes swap right and left child
            if(j+1 <= N){
                if (less(arr[j], arr[j+1])) j++;
            }
            if (!less(arr[root], arr[j])) break;
            exch(arr, root, j);
        // * The root node has now sunken low, call sink recursively with new node to check if it sinks further
            root = j;
        }
    }

    // * * Swim if element is not root, and parent is lesser than node
    public static <T extends Comparable<T>> void swim(T[] arr, int node, int N){
        while(node > 1){
            if(! less(arr[node/2],arr[node])) break;
            exch(arr, node, node/2);
            node = node/2;
        }
    }

    private static <T> void exch(T[] arr, int i, int j){
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    private static <T> boolean less(T v, T w){

        if(((Comparable<T>)v).compareTo(w) < 1 ) return true;
        else return false;
    }


}
