Fusionner le tri en Java

Fusionner le tri en Java

1. introduction

Dans ce tutoriel, nous allons jeter un œil àthe Merge Sort algorithm and its implementation in Java.

Le tri par fusion est l’une des techniques de tri les plus efficaces et il est basé sur le paradigme «diviser et conquérir».

2. L'algorithme

Merge sort is a “divide and conquer” algorithm wherein we first divide the problem into subproblems. Lorsque les solutions pour les sous-problèmes sont prêtes, nous les combinons pour obtenir la solution finale du problème.

C'est l'un des algorithmes qui peuvent être facilement implémentés en utilisant la récursivité car nous traitons des sous-problèmes plutôt que du problème principal.

L'algorithme peut être décrit comme le processus en 2 étapes suivant:

  • Divide: In this step, we divide the input array into 2 halves, le pivot étant le milieu du tableau. Cette étape est effectuée de manière récursive pour tous les demi-tableaux jusqu'à ce qu'il n'y ait plus de demi-tableaux à diviser.

  • Conquer: In this step, we sort and merge the divided arrays de bas en haut et obtenez le tableau trié.

Le diagramme suivant illustre le processus complet de tri par fusion pour un exemple de tableau \ {10, 6, 8, 5, 7, 3, 4}.

Si nous examinons de plus près le diagramme, nous pouvons voir que le tableau est divisé de manière récursive en deux moitiés jusqu'à ce que la taille devienne 1. Une fois que la taille devient 1, les processus de fusion entrent en action et commencent à fusionner les tableaux lors du tri:

image

3. la mise en oeuvre

Pour l'implémentation,we’ll write a mergeSort function which takes in the input array and its length comme paramètres. Ce sera une fonction récursive, nous avons donc besoin de la base et des conditions récursives.

La condition de base vérifie si la longueur du tableau est 1 et elle retournera simplement. Pour le reste des cas, l'appel récursif sera exécuté.

For the recursive case, we get the middle index and create two temporary arrays l[] and r[]. La fonctionmergeSort est alors appelée récursivement pour les deux sous-tableaux:

public static void mergeSort(int[] a, int n) {
    if (n < 2) {
        return;
    }
    int mid = n / 2;
    int[] l = new int[mid];
    int[] r = new int[n - mid];

    for (int i = 0; i < mid; i++) {
        l[i] = a[i];
    }
    for (int i = mid; i < n; i++) {
        r[i - mid] = a[i];
    }
    mergeSort(l, mid);
    mergeSort(r, n - mid);

    merge(a, l, r, mid, n - mid);
}

We then call the merge function which takes in the input and both the sub-arrays and the starting and end indices of both the sub arrays.

La fonctionmerge compare les éléments des deux sous-tableaux un par un et place le plus petit élément dans le tableau d'entrée.

Lorsque nous atteignons la fin de l'un des sous-tableaux, le reste des éléments de l'autre tableau est copié dans le tableau d'entrée, nous donnant ainsi le tableau final trié:

public static void merge(
  int[] a, int[] l, int[] r, int left, int right) {

    int i = 0, j = 0, k = 0;
    while (i < left && j < right) {
        if (l[i] <= r[j]) {
            a[k++] = l[i++];
        }
        else {
            a[k++] = r[j++];
        }
    }
    while (i < left) {
        a[k++] = l[i++];
    }
    while (j < right) {
        a[k++] = r[j++];
    }
}

Le test unitaire du programme:

@Test
public void positiveTest() {
    int[] actual = { 5, 1, 6, 2, 3, 4 };
    int[] expected = { 1, 2, 3, 4, 5, 6 };
    MergeSort.mergeSort(actual, actual.length);
    assertArrayEquals(expected, actual);
}

4. Complexité

Comme le type de fusion est un algorithme récursif, la complexité temporelle peut être exprimée sous la forme de la relation récursive suivante:

T(n) = 2T(n/2) + O(n)

2T(n/2) correspond au temps nécessaire pour trier les sous-tableaux etO(n) temps pour fusionner l'ensemble du tableau.

Une fois résolu,the time complexity will come to O(nLogn).

Ceci est vrai pour le pire, le moyen et le meilleur des cas, car il divisera toujours le tableau en deux, puis fusionnera.

La complexité spatiale de l'algorithme est deO(n) car nous créons des tableaux temporaires dans chaque appel récursif.

5. Conclusion

Dans ce rapide tutoriel, nous avons vu le fonctionnement de l'algorithme de tri par fusion et son implémentation en Java.

Le code de travail complet est disponibleover on GitHub.