package com.hithomelabs.princeton1.module6;

import com.hithomelabs.princeton1.module5.AbstractCustomSorts;

import java.util.Arrays;

public class Merge<E> extends AbstractCustomSorts<E> {
    @Override
    public void sort(E[] arr) {

        int N = arr.length;
        // * * aux is a helper array required for merge
        E[] aux = Arrays.copyOf(arr, N);
        mergesort(arr, aux, 0, N-1);

    }

    private void mergesort(E[] arr, E[] aux, int lo, int hi) {

        if (hi <= lo) return;
        int mid = lo + (hi - lo)/2;
        mergesort(arr, aux, lo, mid);
        mergesort(arr, aux, mid+1, hi);
        merge(arr, aux, lo, mid, hi);

    }

    private void merge(E[] arr, E[] aux, int lo, int mid, int hi) {

        // * * creating backup of original array
        for (int i = lo; i <= hi; i++)
            aux[i] = arr[i];

        int i = lo;
        int j = mid+1;
        for (int k = lo; k <= hi; k++){
            // * If i has already reached mid, no need to compare we insert at pointer k
            if(i > mid) arr[k] = aux[j++];
            else if(j > hi) arr[k] = aux[i++];
            else if(less((Comparable<E>) aux[i], aux[j])) arr[k] = aux[i++];
            else arr[k] = aux[j++];
        }
    }
}


