public class MergeSort {
  /** Metoda do sortowania liczb */
  public static void mergeSort(int[] list) {
    if (list.length > 1) {
      // Sortowanie przez scalanie pierwszej połowy
      int[] firstHalf = new int[list.length / 2];
      System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
      mergeSort(firstHalf);

      // Sortowanie przez scalanie drugiej połowy
      int secondHalfLength = list.length - list.length / 2;
      int[] secondHalf = new int[secondHalfLength];
      System.arraycopy(list, list.length / 2,
        secondHalf, 0, secondHalfLength);
      mergeSort(secondHalf);

      // Scalanie firstHalf z secondHalf w lis
      merge(firstHalf, secondHalf, list);
    }
  }

  /** Scalanie dwóch posortowanych list */
  public static void merge(int[] list1, int[] list2, int[] temp) {
    int current1 = 0; // Indeks bieżącego elementu w list1
    int current2 = 0; // Indeks bieżącego elementu w list2
    int current3 = 0; // Indeks bieżącego elementu w temp

    while (current1 < list1.length && current2 < list2.length) {
      if (list1[current1] < list2[current2])
        temp[current3++] = list1[current1++];
      else
        temp[current3++] = list2[current2++];
    }

    while (current1 < list1.length)
      temp[current3++] = list1[current1++];

    while (current2 < list2.length)
      temp[current3++] = list2[current2++];
  }

  /** Metoda testowa */
  public static void main(String[] args) {
    int[] list = {2, 3, 2, 5, 6, 1, -2, 3, 14, 12};
    mergeSort(list);
    for (int i = 0; i < list.length; i++)
      System.out.print(list[i] + " ");
  }
}
