package Algorithmus.SortierAlgorithmus;

public class MergeSort {
	/* - Zeitkomplexität von O(n log n)
	 * - Raumkomplexität(Space) O(n)
	 * - prinzip Divide (Teilen) und Conquer (Zusammenfügen)
	 * 	Divide (Teilen):  Das Array wird rekursiv in zwei Hälften geteilt, bis jede Teilmenge nur noch ein einziges Element enthält.
	 * 	Conquer (Zusammenfügen): Die kleineren Teilmengen werden dann wieder zusammengeführt und dabei sortiert, um schließlich das vollständig sortierte Array zu erhalten.
	 * - Merge:  zwei bereits sortierte Teilarrays oder -listen zu einem einzigen, sortierten Array zusammengeführen.
	 */
	
	public static void main(String[] args) {
	
		 int[] array = {12, 11, 13, 5, 6, 7};
		 
		 mergSort(array, 0, array.length - 1);

		System.out.println("Sortiertes Array:");
		for (int i : array) 
				System.out.print(i + " ");
		
		
	}
	
	
	public static void mergSort(int[] arr, int left, int right) {
		if (left < right) {
			int middel =(left + right) / 2;
			mergSort(arr,left,middel);
			mergSort(arr,middel + 1,right);
			
			merge(arr,left,middel,right);
		}
	}
	
	public static void merge(int[] arr, int left, int middle, int right) {
		
		// Größe der Teilarrays berechnen
        int n1 = middle - left + 1;
        int n2 = right - middle;

        // Temporäre Arrays erstellen
        int[] leftArray = new int[n1];
        int[] rightArray = new int[n2];

        // Daten in temporäre Arrays kopieren
        for (int i = 0; i < n1; i++)
            leftArray[i] = arr[left + i];
        for (int j = 0; j < n2; j++)
            rightArray[j] = arr[middle + 1 + j];

        // Zusammenführen der temporären Arrays
        int i = 0, j = 0;
        int k = left;
        while (i < n1 && j < n2) {
            if (leftArray[i] <= rightArray[j]) 
            	arr[k++] = leftArray[i++];
            else 
            	arr[k++] = rightArray[j++];
        }

        // Restliche Elemente von leftArray kopieren
        while (i < n1) 
        	arr[k++] = leftArray[i++];

        // Restliche Elemente von rightArray kopieren
        while (j < n2) 
        	arr[k] = rightArray[j++];
	}

}
