web-dev-qa-db-fra.com

Comment fonctionne Radix Sort?

Je ne sais pas pourquoi c'est si difficile pour moi d'envelopper ma tête. J'ai parcouru les pages wiki et le pseudo-code (ainsi que le code réel) en essayant de comprendre le fonctionnement des algorithmes de tri radix (en ce qui concerne les compartiments).

Suis-je en train de chercher la mauvaise chose ici? Dois-je envisager le tri par seau peut-être? Quelqu'un peut-il me donner une version abrégée de la façon dont cela fonctionne? Pour référence, voici un bloc de code qui soi-disant effectue un tri radix:

// Sort 'size' number of integers starting at 'input' according to the 'digit'th digit
// For the parameter 'digit', 0 denotes the least significant digit and increases as significance does
void radixSort(int* input, int size, int digit)
{
    if (size == 0)
        return;

    int[10] buckets;    // assuming decimal numbers

    // Sort the array in place while keeping track of bucket starting indices.
    // If bucket[i] is meant to be empty (no numbers with i at the specified digit),
    // then let bucket[i+1] = bucket[i]

    for (int i = 0; i < 10; ++i)
    {
        radixSort(input + buckets[i], buckets[i+1] - buckets[i], digit+1);
    }
}

Et j'ai également examiné des solutions non récursives:

void radixsort(int *a, int arraySize)
{
    int i, bucket[sortsize], maxVal = 0, digitPosition =1 ;
    for(i = 0; i < arraySize; i++) {
        if(a[i] > maxVal) maxVal = a[i];
    }

    int pass = 1; 
    while(maxVal/digitPosition > 0) {
        // reset counter 
        int digitCount[10] = {0};

        // count pos-th digits (keys) 
        for(i = 0; i < arraySize; i++)
            digitCount[a[i]/digitPosition%10]++;

        // accumulated count 
        for(i = 1; i < 10; i++)
            digitCount[i] += digitCount[i-1];

        // To keep the order, start from back side
        for(i = arraySize - 1; i >= 0; i--)
            bucket[--digitCount[a[i]/digitPosition%10]] = a[i];

        for(i = 0; i < arraySize; i++)
            a[i] = bucket[i];

        cout << "pass #" << pass++ << ": ";
        digitPosition *= 10;
    } 

}

Plus précisément, cette ligne me pose des problèmes. J'ai essayé de le parcourir avec un stylo et du papier, mais je n'arrive toujours pas à comprendre ce que cela fait:

   // To keep the order, start from back side
        for(i = arraySize - 1; i >= 0; i--)
            bucket[--digitCount[a[i]/digitPosition%10]] = a[i];
37
MrDuk

En mathématiques, radix signifie base, où la décimale serait la base 10. Imaginez que vous ayez des nombres dont certains ont plus d'un chiffre comme

5, 213, 55, 21, 2334, 31, 20, 430

Par souci de simplicité, disons que vous souhaitez utiliser le radix décimal (= 10) pour le tri. Ensuite, vous commenceriez par séparer les nombres par des unités, puis les recomposer; ensuite, vous sépareriez les nombres par dizaines, puis les recomposeriez; puis par centaines et ainsi de suite jusqu'à ce que tous les nombres soient triés. Chaque fois que vous bouclez, lisez simplement la liste de gauche à droite. Vous pouvez également imaginer que vous séparez les nombres en seaux. Voici une illustration utilisant 5, 213, 55, 21, 2334, 31, 20, 430

Séparer par unités:

  • zéros: 20, 430

  • ceux: 21, 31

  • deux:

  • trois: 213

  • quatre pattes: 2334

  • cinq: 5, 55

    De retour ensemble: 20, 430, 21, 31, 213, 2334, 5, 55

Pour les réassembler, lisez d'abord le compartiment zeroes, puis le compartiment ones, et ainsi de suite, jusqu'à ce que vous lisiez le compartiment nines.

Séparé par dizaines:

  • zéros: 05

  • ceux: 213

  • deux: 20, 21

  • trois: 430, 31, 2334,

  • à quatre pattes:

  • cinq: 55

    De retour ensemble: 5, 213, 20, 21, 430, 31, 2334, 55

Séparez par centaines:

  • zéros: 005, 020, 021, 031, 055

  • ceux:

  • deux: 213

  • trois: 2334

  • quatre pattes: 430

  • cinq:

    De retour ensemble: 5, 20, 21, 31, 55, 213, 2334, 430

Séparé par milliers:

  • zéros: 0005, 0020, 0021, 0031, 0055, 0213, 0430

  • ceux:

  • deux: 2334

  • trois:

  • à quatre pattes:

  • cinq:

    De retour ensemble: 5, 20, 21, 31, 55, 213, 430, 2334

Vous avez maintenant terminé. J'ai vu un bon code pour cela sur Geekviewpoint à la fois en Java et en python

100
Konsol Labapen

Pensez à un jeu de cartes. Vous triez d'abord par costume en quatre piles. Ensuite, vous mettez ces quatre piles les unes sur les autres et les triez maintenant en 13 piles en fonction du rang. Mettez-les ensemble et vous avez maintenant un jeu trié.

Il s'agit du flux de base de quicksort.

Pour la 1ère passe: nous trions le tableau sur la base du chiffre le moins significatif (1 place) en utilisant le tri par comptage. Notez que 435 est inférieur à 835, car 435 s'est produit en dessous de 835 dans la liste d'origine.

Pour la 2e passe: nous trions le tableau sur la base du chiffre suivant (10s) en utilisant le tri par comptage. Notez qu'ici 608 est inférieur à 704, car 608 s'est produit en dessous de 704 dans la liste précédente, et de même pour (835, 435) et (751, 453).

Pour la troisième passe: nous trions le tableau sur la base du chiffre le plus significatif (100s) en utilisant le tri par comptage. Notez qu'ici 435 est inférieur à 453, car 435 s'est produit en dessous de 453 dans la liste précédente, et de même pour (608, 690) et (704, 751).

Pour plus de détails vous pouvez vous référer à ce blog sur codingeek et avoir une compréhension claire .

1
Hitesh Garg