web-dev-qa-db-fra.com

Quel est le meilleur algorithme de tri pour trier un tableau de petits entiers?

Comme pour le titre de la question, si le tableau a une longueur impaire et si les éléments du tableau sont numérotés de 1 à 10. 

Exemple, 

3 6 8 1 3 7 7 9 4 1

Je pensais à utiliser Heapsort ? Puisqu'il s'agit d'un tableau, fusionner les types et les types d'insertion nécessitent un décalage et ne seraient pas aussi efficaces.

18
user236501

les éléments du tableau sont numérotés de 1 à 10.

Avec cette restriction, sorte de comptage sera beaucoup plus efficace que n'importe quel algorithme de tri à usage général - c'est O (n)

31
Michael Borgwardt

Ceci est mon exemple de tri de comptage

static int[] countingSort(int[] numbers) {
    int max = numbers[0];
    for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] > max)
            max = numbers[i];
    }

    int[] sortedNumbers = new int[max+1];

    for (int i = 0; i < numbers.length; i++) {
        sortedNumbers[numbers[i]]++;
    }

    int insertPosition = 0;

    for (int i = 0; i <= max; i++) {
            for (int j = 0; j < sortedNumbers[i]; j++) {
                    numbers[insertPosition] = i;
                    insertPosition++;
            }
    }
    return numbers;
}
7
ben_muc

Éditer: un tri de comptage est probablement optimal étant donné la contrainte que les éléments ne vont que de 1 à 10. Un tri de comptage appliqué à ce problème s'exécutera dans le temps O(n). Un type de fusion (comme recommandé ci-dessous) ne fonctionnera pas mieux que O(nlogn) time. Mettre en parallèle une sorte de comptage pourrait être intéressant. Attribuez simplement un sous-tableau avec n/p éléments à chaque processeur. Chaque processeur aurait son propre tableau de comptage de taille 9. Cette étape devrait prendre O(n/p) temps. Ensuite, consolidez tous les tableaux de comptage en un seul tableau, ce qui devrait prendre O(p) temps. Je n'ai pas complètement réfléchi à la dernière étape de la sorte de comptage où les éléments sont placés dans l'ordre, mais il semble que tant que les éléments du tableau de comptage sont atomiques, vous pouvez affecter n/p sections du tableau d'origine à un individu. processeurs et réaliser une certaine parallélisation. Il y aurait cependant des conflits au niveau des éléments individuels du tableau de comptage, ce qui réduirait potentiellement considérablement la simultanéité. Vous pourrez peut-être affecter des sous-sections du tableau count à p processeurs et vous reviendrez au O(n/p) runtime, si les éléments sont distribués de manière assez uniforme, mais vous seriez limité à 10 processeurs. Si les éléments ne sont pas répartis de manière égale, un ou plusieurs processeurs pourraient effectuer une plus grande partie du travail. C'est une excellente question. pouvez-vous faire un tri de comptage dans O(n/p) fois?

Quicksort est un excellent algorithme de tri sur place qui s'exécute rapidement et conserve la mémoire. Toutefois, étant donné que les éléments se situent dans la plage allant de 1 à 10, si vous triez un grand nombre d’éléments, vous obtiendrez de grandes exécutions du même nombre, soit initialement, soit à des moments intermédiaires du tri. Les tableaux en ordre ou les sous-tableaux peuvent vraiment nuire aux performances d'un Quicksort.

Si vous ne vous souciez pas de la mémoire, un simple Mergesort suffirait. Mergesort compte parmi les algorithmes de tri standard les plus rapides.

L'implémentation par défaut de Collections.sort () dans Java 7 est un algorithme Mergesort adapté de "TimSort". L'implémentation par défaut de Arrays.sort () dans Java 7 est un Quicksort à double pivot.

Si vous souhaitez aller en parallèle, un Parallel Quicksort peut donner de bons résultats sur des baies de grande taille avec un petit nombre de processeurs, mais avec les mêmes limites que le Quicksort séquentiel. PSRS peut aider à s’adapter à un plus grand nombre de processeurs.

2
broadbear

S'il n'y a que 10 éléments, cela ne vaut pas la peine de s'en inquiéter. S'il y en a un million, cela pourrait commencer à devenir important.

2
user207421

Vous devriez envisager de regarder ceci pour le graphique de complexité Tableau de comparaison de complexité .

La comparaison de l'algorithme de tri est basée sur le meilleur, le moyen, le pire scénario pour la complexité du temps et de l'espace. Basée sur ce graphique, vous pouvez voir Tri par comptage L'approche convient le mieux à la complexité de l'espace et du temps. Une autre méthode comparable est Radix Sort.

Plus mauvaise complexité [temps, espace] de "Compter le tri": - [O (n + k), O (k)].

Plus mauvaise complexité [temps, espace] de "type de base": - [O (nk), O (n + k)]. 

1
bibek koirala

QuickSort est un algorithme Divide and Conquer. Il sélectionne un élément en tant que pivot et partitionne la matrice donnée autour du pivot sélectionné, puis répète le processus. Il existe de nombreuses versions de quickSort qui sélectionnent le pivot de différentes manières.

1
sdfahklj

Compter le tri sera le mieux dans ce scénario. 

En supposant que les données sont des entiers, dans une plage de 0 à k. Créez un tableau de taille K pour suivre le nombre d'éléments affichés (3 éléments de valeur 0, 4 éléments de valeur 1, etc.). Compte tenu de ce nombre, vous pouvez indiquer la position d’un élément - tous les 1 doivent être placés après les 0 (il y en a 3). Par conséquent, le 1 commence par l’article 4. Ainsi, nous pouvons numériser les éléments et les insérer dans leur position appropriée.

La création du tableau de nombres est O (N) Insérer les éléments à leur position correcte est O (N) stable.

0
Sai prateek

ceci est un exemple de tri simple (tri par insertion)

private static void insertionSort(int[] a) {

    // [230, 23, 45, 34, 98]
    for (int j = 2; j < a.length; j++) {

        int key = a[j];
        int i = j - 1;

        while (i > 0 && a[i] > key) {
            a[i + 1] = a[i];
            i--;
        }
        a[i + 1] = key;
    }

    System.out.println("sorted array: " + Arrays.toString(a));
}
0
Yousuf Qureshi