web-dev-qa-db-fra.com

Pourquoi ne pas toujours utiliser le tri en tas

L'algorithme de tri Heap Sort semble avoir la pire complexité de O (nlogn), et utilise O(1) espace pour l'opération de tri.

Cela semble meilleur que la plupart des algorithmes de tri. Alors, pourquoi ne pas utiliser Heap Sort toujours comme algorithme de tri (et pourquoi les gens utilisent-ils des mécanismes de tri comme le tri par fusion ou le tri rapide)?

De plus, j'ai vu des gens utiliser le terme "instabilité" avec le tri par tas. Qu'est-ce que cela implique?

63
Saket

Un tri stable conserve l'ordre relatif des éléments qui ont la même clé. Par exemple, imaginez que votre ensemble de données contient des enregistrements avec un identifiant d'employé et un nom. L'ordre initial est le suivant:

1, Jim
2, George
3, Jim
4, Sally
5, George

Vous souhaitez trier par nom. Un tri stable organisera les éléments dans cet ordre:

2, George
5, George
1, Jim
3, Jim
4, Sally

Notez que les enregistrements en double pour "George" sont dans le même ordre relatif qu'ils l'étaient dans la liste initiale. Idem avec les deux disques "Jim".

Un tri instable peut organiser les éléments comme ceci:

5, George
2, George
1, Jim
3, Jim
4, Sally

Heapsort n'est pas stable car les opérations sur le tas peuvent modifier l'ordre relatif des éléments égaux. Toutes les implémentations Quicksort ne sont pas stables. Cela dépend de la façon dont vous implémentez le partitionnement.

Bien que Heapsort ait une pire complexité de O(n log(n)), cela ne raconte pas toute l'histoire. Dans la mise en œuvre dans le monde réel, il existe des facteurs constants que l'analyse théorique ne prend pas en compte. Dans le cas de Heapsort vs Quicksort, il s'avère qu'il existe des moyens (médiane de 5, par exemple) pour rendre les pires cas de Quicksort très rares. De plus, la maintenance d'un tas n'est pas gratuite.

Étant donné un tableau avec une distribution normale, Quicksort et Heapsort s'exécuteront tous les deux dans O(n log(n)). Mais Quicksort s'exécutera plus rapidement car ses facteurs constants sont plus petits que les facteurs constants pour Heapsort. Pour faire simple, le partitionnement est plus rapide que la maintenance du tas.

112
Jim Mischel

Le tri de tas a la pire complexité de O(n log(n)). Pourtant, des études empiriques montrent que généralement le tri rapide (et d'autres algorithmes de tri) est considérablement plus rapide que le tri en tas, bien que son pire cas de complexité soit O(n²): http://www.cs.auckland.ac.nz/~jmor159/PLDS210/qsort3.html

Aussi, à partir de article de tri rapide sur Wikipedia:

Le concurrent le plus direct du quicksort est le heapsort. Le temps d'exécution le plus défavorable de Heapsort est toujours O (n log n). Mais, le tri actif est supposé être en moyenne un peu plus lent que le tri rapide en place standard. Ceci est encore débattu et en recherche, certaines publications indiquant le contraire. [13] [14] Introsort est une variante de quicksort qui passe en heapsort lorsqu'un mauvais cas est détecté pour éviter le pire temps de fonctionnement de quicksort. S'il est connu à l'avance que le heapsort va être nécessaire, son utilisation directe sera plus rapide que l'attente d'un introsort pour y basculer.

Cependant, le tri rapide ne doit jamais être utilisé dans des applications qui nécessitent une garantie de temps de réponse!

Source sur Stackoverflow: Quicksort vs heapsort

9
Jean Logeart

Il n'y a pas de solution miracle ...

Juste pour mentionner un autre argument que je n'ai pas encore vu ici:

Si votre jeu de données est vraiment énorme et ne tient pas dans la mémoire, le tri par fusion fonctionne comme un charme. Il est fréquemment utilisé dans les clusters où l'ensemble de données peut s'étendre sur des centaines de machines.

6
Karoly Horvath

Lorsque j'ai travaillé pendant une courte période sur des ordinateurs Tandem Non-Stop au milieu des années 80, j'ai remarqué que la routine de tri du système était HeapSort, précisément parce qu'elle offrait des performances NlogN garanties. Je ne connais personne qui ait eu aucune raison de l'utiliser, donc je ne sais pas comment cela a fonctionné dans la pratique. J'aime le tri sélectif, mais en plus des inconvénients mentionnés ci-dessus, j'ai entendu dire qu'il utilise mal les mémoires modernes, car il rend les accès à la mémoire partout, tandis que le tri rapide et même les petits types de radix finissent par mélanger un nombre relativement petit de flux de lectures et d'écritures séquentielles - les caches sont donc plus efficaces.

0
mcdowella

Des algorithmes de tri stables maintiennent l'ordre relatif des enregistrements avec des clés égales

Certaines applications aiment avoir ce genre de stabilité, la plupart s'en moquent, par exemple Google est votre ami.

Quant à vous affirmer que "les gens utilisent des mécanismes de tri comme le tri par fusion ou le tri rapide", je parierais que la plupart des gens utilisent tout ce qui est intégré dans leur langage et ne pensent pas beaucoup à l'algorithme de tri. Ceux qui roulent eux-mêmes n'ont probablement pas entendu parler du tri par tas (le dernier est une expérience personnelle).

La dernière et principale raison est que tout le monde ne voudra pas d'un tas trié. Certaines personnes veulent la liste triée. Si le patron moyen de Joe Programmer dit "trier cette liste", et Joe dit "Voici cette structure de données de tas dont vous n'avez jamais entendu parler, patron!", Le prochain examen des performances de Joe ne sera pas si génial.

0
Kane