There's an in-place (MSB) radix sort.
Il va quelque chose comme ceci:
- Commencez avec le premier bit.
Déplacez tous les éléments dont le bit est égal à 0 vers la gauche
et tous ceux dont le bit est égal à 1 sur la droite.
Vous faites cela de la même manière que le quicksort en vous déplaçant des deux côtés vers le milieu, en échangeant les 1 sur la gauche avec les 0 sur la droite.
- Recourber à la fois du côté gauche et du côté droit en tenant compte du bit suivant.
Le processus ressemble à ceci:
↓ ↓
0... 1...
--------------- ---------------
↓ ↓ ↓ ↓
00... 01... 10... 11...
------- ------- ------- -------
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
000 001 010 011 101 110 110 111
--- --- --- --- --- --- --- ---
...
La complexité du temps est O(bits*n)
et la complexité de l'espace est O(bits)
. Donc, avec un nombre constant de bits, la complexité temporelle est de O(n)
et la complexité de l'espace est de O(1)
Il est également possible de le faire en utilisant comptage sorte (avec en même temps et de la complexité de l'espace).
- Compter le nombre de chaque élément. En utilisant ceci, vous pouvez déterminer où placer ces éléments dans le tableau.
Créer une table de correspondance (index de mappage à décalage, peut être un tableau) contenant tous les points de départ ci-dessus, qui seront utilisés pour déterminer où l'élément suivant doit aller.
Maintenant, vous faites une boucle sur la matrice et permutez chaque élément qui n'a pas sa place à la première place, puis faites de même avec chaque élément que nous avons échangé, jusqu'à ce que l'élément actuel soit à sa place.
Augmentez le décalage de l'élément concerné dans la table de recherche à chaque étape. Notez qu'il est impossible d'échanger deux fois le même élément, donc ce sera le temps linéaire.
Tout cela semble très confus, alors voici un exemple:
4 5 3 1 2 3 4 4 1 5 4 3 2 3
// counts:
1: 2, 2: 2, 3: 4, 4: 4, 5: 2
// the starting points (offsets) based on the counts:
1 at position 0
2 at position (offset of 1)+(count of 1) = 0+2 = 2
3 at position (offset of 2)+(count of 2) = 2+2 = 4
4 at position (offset of 3)+(count of 3) = 4+4 = 8
5 at position (offset of 4)+(count of 4) = 8+4 = 12
// sorting:
4 5 3 1 2 3 4 4 1 5 4 3 2 3 // out of place, swap with offsets[4] = 8 (offsets[4]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // in correct position, moving on (offsets[1]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // swap with offsets[5] = 12 (offsets[5]++)
^
1 2 3 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 2 (offsets[2]++)
^
1 3 2 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[3] = 4 (offsets[3]++)
^
1 2 2 1 3 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 3 (offsets[2]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[1]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[2]++)
^
Vous avez l'idée ...
Notez que la taille de la table de comptage et la table de consultation sont O(max value)
, qui est O(1)
si chaque nombre contient un nombre fixe de bits.
Et vous faites une quantité constante de travail pour chaque élément, donc c'est O(n)
temps.
Le tri de base MSD sur place est ce que je cherchais, merci! – Konrad
@Konrad J'ai ajouté une autre solution à ma réponse basée sur le tri par comptage. – Dukeling