Tri des bulles en Java

Tri à bulles en Java

1. introduction

Dans cet article rapide, nous allons explorer en détail l'algorithme Bubble Sort, en nous concentrant sur une implémentation Java.

C'est l'un des algorithmes de tri les plus simples; the core idea is tokeep swapping adjacent elements d'un tableau s'ils sont dans un ordre incorrect jusqu'à ce que la collection soit triée.

Les petits éléments «apparaissent» en haut de la liste lorsque nous itérons la structure de données. Par conséquent, la technique est connue sous le nom de tri à bulles.

Comme le tri est effectué par permutation, on peut dire qu'il effectue un tri sur place.

De plus,if two elements have same values, resulting data will have their order preserved - ce qui en fait un tri stable.

2. Méthodologie

Comme mentionné précédemment, pour trier un tableau, nous le parcourons en comparant les éléments adjacents et en les échangeant si nécessaire. Pour un tableau de taillen, nous effectuonsn-1 de telles itérations.

Prenons un exemple pour comprendre la méthodologie. Nous souhaitons trier le tableau dans l'ordre croissant:

4 2 1 6 3 5

Nous commençons la première itération en comparant 4 et 2; ils ne sont certainement pas dans le bon ordre. L'échange entraînerait:

[2 4] 1 6 3 5

Maintenant, répétons la même chose pour 4 et 1:

2[14] 6 3 5

Nous continuons à le faire jusqu'à la fin:

2 1 [4 6] 3 5

2 1 4[36] 5

2 1 4 3[5 6]

Comme nous pouvons le constater, à la fin de la première itération, nous avons obtenu le dernier élément à sa juste place. Maintenant, tout ce que nous avons à faire est de répéter la même procédure lors de nouvelles itérations. Sauf que nous excluons les éléments déjà triés.

Dans la deuxième itération, nous allons parcourir tout le tableau à l'exception du dernier élément. De même, pour la 3ème itération, nous omettons les 2 derniers éléments. En général, pour la k-ième itération, on itère jusqu'à l'indicen-k (exclu). À la fin des itérations den-1, nous obtiendrons le tableau trié.

Maintenant que vous comprenez la technique, plongeons dans la mise en œuvre.

3. la mise en oeuvre

Implémentons le tri pour l'exemple de tableau dont nous avons parlé en utilisant l'approche Java 8:

void bubbleSort(Integer[] arr) {
    int n = arr.length;
    IntStream.range(0, n - 1)
    .flatMap(i -> IntStream.range(1, n - i))
    .forEach(j -> {
        if (arr[j - 1] > arr[j]) {
            int temp = arr[j];
            arr[j] = arr[j - 1];
            arr[j - 1] = temp;
            }
     });
}

Et un test rapide de JUnit pour l’algorithme:

@Test
public void whenSortedWithBubbleSort_thenGetSortedArray() {
    Integer[] array = { 2, 1, 4, 6, 3, 5 };
    Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
    BubbleSort bubbleSort = new BubbleSort();
    bubbleSort.bubbleSort(array);

    assertArrayEquals(array, sortedArray);
}

4. Complexité et optimisation

Comme nous pouvons le voir,for the average and the worst case,the time complexity isO(n^2).

De plus,the space complexity, même dans le pire des scénarios,is O(1) as Bubble sort algorithm doesn’t require any extra memory et le tri a lieu dans le tableau d'origine.

En analysant soigneusement la solution, nous pouvons voir queif no swaps are found in an iteration, we don’t need to iterate further.

Dans le cas de l'exemple discuté plus tôt, après la 2ème itération, on obtient:

1 2 3 4 5 6

Dans la troisième itération, nous n'avons pas besoin d'échanger une paire d'éléments adjacents. Nous pouvons donc ignorer toutes les itérations restantes.

Dans le cas d'un tableau trié, l'échange ne sera pas nécessaire dans la première itération elle-même - ce qui signifie que nous pouvons arrêter l'exécution. C'est le meilleur des cas et lestime complexity of the algorithm is O(n).

Maintenant, mettons en œuvre la solution optimisée.

public void optimizedBubbleSort(Integer[] arr) {
    int i = 0, n = arr.length;
    boolean swapNeeded = true;
    while (i < n - 1 && swapNeeded) {
        swapNeeded = false;
        for (int j = 1; j < n - i; j++) {
            if (arr[j - 1] > arr[j]) {
                int temp = arr[j - 1];
                arr[j - 1] = arr[j];
                arr[j] = temp;
                swapNeeded = true;
            }
        }
        if(!swapNeeded) {
            break;
        }
        i++;
    }
}

Vérifions la sortie de l'algorithme optimisé:

@Test
public void
  givenIntegerArray_whenSortedWithOptimizedBubbleSort_thenGetSortedArray() {
      Integer[] array = { 2, 1, 4, 6, 3, 5 };
      Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
      BubbleSort bubbleSort = new BubbleSort();
      bubbleSort.optimizedBubbleSort(array);

      assertArrayEquals(array, sortedArray);
}

5. Conclusion

Dans ce didacticiel, nous avons vu le fonctionnement de Bubble Sort et son implémentation en Java. Nous avons également vu comment il peut être optimisé. Pour résumer, il s'agit d'un algorithme stable en place, avec une complexité temporelle:

  • Cas le plus mauvais et moyen: O (n * n), lorsque le tableau est en ordre inverse

  • Meilleur cas: O (n), lorsque le tableau est déjà trié

L'algorithme est populaire en infographie, en raison de sa capacité à détecter certaines petites erreurs de tri. Par exemple, dans un tableau presque trié, seuls deux éléments doivent être échangés pour obtenir un tableau complètement trié. Bubble Sort peut corriger de telles erreurs (par ex. trier ce tableau) en temps linéaire.

Comme toujours, le code pour l'implémentation de cet algorithme peut être trouvéover on GitHub.