import java.util.Arrays;
import java.util.logging.Logger;
public class ArrayMerge {
    private final static Logger log = Logger.getLogger(ArrayMerge.class.getName());
    public static int[] quicksort(final int[] source) {
        return sort(source, 0, source.length-1);
    }
    public static int[] sort(final int[] source, final int start, final int end) {
        log.info("sort: " + start + " - " + end);
        int[] result;
        if (end - start > 0) {
            int[] first = sort(source, start, start + (end-start)/2);
            int[] second = sort(source, start + (end-start)/2 + 1, end);
            result = merge(first, second);
        } else {
            result = new int[] { source[start] } ;
        }
        log.info("sort(" + Arrays.toString(source) + ", " + start + ", " + end + ") = " + Arrays.toString(result));
        return result;
    }
    public static int[] merge(final int[] first, final int[] second) {
        return merge(first, first.length, second, second.length);
    }
    public static int[] merge(final int[] first, final int lengthFirst, final int[] second, final int lengthSecond) {
        // Normalen QuickSort Algorithmus könnte man durch ersetzen von lengthFirst und lengthSecond durch
        // first.length und second.length bekommen.
        int[] result = new int[lengthFirst + lengthSecond];
        int firstIndex = 0;
        int secondIndex = 0;
        int resultIndex = 0;
        while (resultIndex < result.length) {
            if (firstIndex < lengthFirst && secondIndex < lengthSecond) {
                // We take minimum from first and second
                if (first[firstIndex] < second[secondIndex]) {
                    result[resultIndex] = first[firstIndex];
                    firstIndex++;
                } else {
                    result[resultIndex] = second[secondIndex];
                    secondIndex++;
                }
            } else if (firstIndex < lengthFirst) {
                // We take element from first
                result[resultIndex] = first[firstIndex];
                firstIndex++;
            } else {
                // We take element from second
                result[resultIndex] = second[secondIndex];
                secondIndex++;
            }
            resultIndex++;
        }
        log.info("Merged: " + Arrays.toString(first) + " + " + Arrays.toString(second) + " = " + Arrays.toString(result));
        return result;
    }
    public static void main (String[] args) {
        // testing the QuickSort
        int[] array = { 17, 32, 3, 45, 1, 7 };
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(ArrayMerge.quicksort(array)));
        // Now merging the Arrays with ignoring of the highest Element.
        int[][] twodimarray = { { 21, 14, 7 },
                { 8, 32, 24, 16 },
                { 9, 18, 27} };
        int[] result = new int[0];
        for(int[] subArray: twodimarray) {
            if (subArray.length > 1)
                result = merge(result, result.length, quicksort(subArray), subArray.length - 1);
        }
        System.out.println(Arrays.toString(result));
    }
}