Le pire cas

35

J'ai du mal à trouver de bonnes ressources qui donnent le pire des cas en place stable algorithme de tri. Est-ce que quelqu'un connaît de bonnes ressources?O(nlnn)

Juste un rappel, en place signifie qu’il utilise le tableau transmis et que l’algorithme de tri n’est autorisé qu’à utiliser un espace supplémentaire constant. Stable signifie que les éléments avec la même clé apparaissent dans le même ordre dans le tableau trié que dans l'original.

Par exemple, le tri par fusion naïf est le pire des cas et stable, mais utilise espace supplémentaire. Le tri rapide standard peut être rendu stable, est en place mais est le cas le plus défavorable . Heapsort est en place, dans le pire des cas mais n'est pas stable. Wikipedia a un bon tableau indiquant quels algorithmes de tri ont quels inconvénients. Notez qu’ils ne répertorient aucun algorithme de tri contenant les trois conditions de stabilité, le cas le plus défavorable et le fait d’être en place.O ( nO(nlnn)O ( n 2 ) O ( n ln n )O(n)O(n2)O(nlnn)O(nlnn)

J'ai trouvé un article intitulé "Practical in place mergesort" de Katajainen, Pasanen et Teuhola, qui prétend avoir le cas le plus défavorable à la place de la variante mergesort stable. Si je comprends bien leurs résultats, ils utilisent (bottom-up?) Mergesort de manière récursive sur le premier du tableau et ce dernier du tableau et utilisent le second comme espace de travail pour effectuer la fusion. Je suis toujours en train de le lire, donc j'apprécierais plus si j'interprète correctement leurs résultats.1O(nlnn) 114 11214

Je serais également très intéressé par le pire des cas en place de quicksort stable. D'après ce que j'ai compris, modifier le tri rapide comme étant le cas le plus défavorable nécessite de choisir un pivot approprié qui détruirait la stabilité dont il jouirait normalement normalement.O ( n ln n )O(nlnn)O(nlnn)

Ceci est purement d’intérêt théorique et je n’ai aucune application pratique. Je voudrais juste savoir l'algorithme qui a ces trois caractéristiques.

utilisateur834
la source
Il y a une question similaire sur SO ici avec une réponse qui donne la référence que j'ai fournie dans la question. Je crois que ce n'est pas une question en double, je demande des précisions supplémentaires, davantage de documentation et, avec un peu de chance, une description de l'algorithme.
user834
1
Voir cette question sur math.stackexchange.com.
Tsuyoshi Ito
Pourquoi une manière différente de sélectionner un pivot dans QuickSort détruirait-elle sa stabilité?
svick
@svick, le seul moyen de faire de QuickSort le pire cas est de choisir le pivot plus intelligemment que de façon aléatoire. J'ai appris à le faire en utilisant l'algorithme de sélection, qui utilise l'algorithme de la médiane des médianes, qui détruit la stabilité. Si j'ai manqué quelque chose, s'il vous plaît faites le moi savoir. O(nlnn)
user834
@TsuyoshiIto, envisagez d'en faire une réponse. De plus, si vous pouviez donner un bref aperçu de l'algorithme, je pense que cela serait également très utile.
user834

Réponses:

6

Il existe plusieurs algorithmes qui correspondent à ce qui précède, et la plupart ont été inventés au cours des 30 dernières années.

Probablement la plus gentille est la classe d'algorithmes appelée Block sort , y compris la version (appelée WikiSort) de Kim et Kutzner en 2008. Elle n'est pas seulement stable et complètement en place (mémoire O (1) dans le modèle transdichotomique), elle est également adaptatif, et prendra donc moins de mesures pour trier les listes presque triées, convergeant vers des comparaisons O (n) dans le cas d’une liste déjà triée. Vous pouvez trouver une implémentation en C, C ++ et Java ici: https://github.com/BonzaiThePenguin/WikiSort

L’algorithme GrailSort (également une sorte de bloc) de Huang et Langston (1989-1992), qui surpasse de loin WikiSort sur plusieurs types de cas de test, est également intéressant. Une implémentation C ++ est disponible ici: https://github.com/Mrrl/GrailSort

quintopie
la source
8

Vous pouvez écrire un mergesort stable sur place. Voir cela pour plus de détails. Dans les propres mots de l'auteur:

Une belle en place - algorithme de fusion. Testez-le sur des tableaux inversés pour comprendre le fonctionnement des rotations. Le type stable le plus rapide en place connu. Aucun risque d'explosion d'une pile. Coût: un nombre relativement élevé de déménagements. La pile peut encore être chère aussi. Il s'agit d'un type de fusion avec une fusion intelligente sur place qui "fait pivoter" les sous-tableaux. Ce code est littéralement copié à partir de la bibliothèque stl C ++ et traduit en Java.

Je ne vais pas copier le code ici, mais vous pouvez le trouver en cliquant sur le lien ou en consultant la STL C ++. S'il vous plaît laissez-moi savoir si vous voudriez que j'essaye de fournir une description plus détaillée de ce qui se passe ici.

Patrick87
la source
8
O(lnn)O(1)O(lnn)
Knuth aborde également cette question dans TAoCP.
Raphaël
O(nln2n)
1

Veuillez prendre ceci comme un long commentaire sur quelques réflexions pratiques. Bien que ce ne soit pas une réponse à votre question, je pense que cette discussion sur Python pourrait vous intéresser:

lg(N!)N1

[...]

La fusion des longueurs adjacentes des longueurs A et B sur place est très difficile . On sait que des constructions théoriques peuvent le faire, mais elles sont trop difficiles et lentes pour une utilisation pratique . Mais si nous avons une mémoire temporaire égale à min (A, B), c'est facile.

Source: bugs.python.org , auteur: Tim Peters

O(nlogn)

Notez également que Timsort fonctionne bien sur les tableaux déjà triés.

Donc, Python utilise Timsort (qui est Mergesort avec quelques ajustements) et, alors que j’avais cherché l’implémentation de Java il ya quelques années, c’était aussi Mergesort (je pense qu’ils utilisent maintenant Timsort).

Martin Thoma
la source