Shell assortissent

Le Shell assortissent est un algorithme de tri qui est une généralisation de la sorte d'insertion , avec deux observations :
la sorte d'insertion est efficace si l'entrée est " ; presque sorted" ; , et
la sorte d'insertion est en général inefficace parce qu'elle déplace des valeurs juste une position à la fois.

Histoire

Shell assortissent est baptisé du nom de son inventeur, le Donald Shell , qui a édité l'algorithme en 1959. Quelques manuels et références plus anciens appellent ceci le " ; Coquille-Metzner" ; sorte après Marlene Metzner Norton , mais selon Metzner, " ; Je n'ai eu rien à faire avec la sorte, et mon nom devrait jamais n'avoir été attaché à it." ;

Exécution

L'exécution originale effectue des comparaisons et des échanges du O ( n 2) dans le pire des cas. Une modification mineure donnée dans le livre de V. Pratt a amélioré la limite à O ( n de n log2). C'est plus mauvais que les sortes optimales de comparaison de qui sont O ( n de notation de n ).

Shell assortissent améliore la sorte d'insertion en comparant des éléments séparés par un espace de plusieurs positions. Ceci laisse un élément prendre le " ; un plus grand steps" ; vers sa position prévue. Des passages multiples au-dessus des données sont pris avec de plus petites et plus petites tailles d'espace. La dernière étape de la sorte de Shell est une sorte d'insertion plate, mais d'ici là, le choix de données est garanti pour être presque assorti.

Considérer une petite valeur qui est au commencement stockée dans la fin fausse de la rangée . Using une sorte d'O ( n 2) telle que le tri par échange de paire de clés ou la sorte d'insertion , elle prendra rudement des comparaisons et des échanges du n pour déplacer cette valeur toute la manière à l'autre fin de la rangée. Shell assortissent déplace d'abord des valeurs using des tailles de pas de géant, ainsi une petite valeur déplacera un long chemin vers sa position finale, avec juste quelques comparaisons et échanges.

On peut visualiser Shellsort de la façon suivante : arranger la liste dans une table et assortir les colonnes (using une sorte d'insertion ). Répéter ce processus, chaque fois avec un plus petit nombre de plus longues colonnes. À l'extrémité, la table a seulement une colonne. Tandis que la transformation de la liste en table le facilite pour visualiser, l'algorithme lui-même fait son tri sur place (en incrémentant l'index par la taille d'étape, c. using i += step_size au lieu de i++).

Par exemple, considérer une liste de nombres comme le 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 . Si nous commencions par une étape-taille de 5, nous pourrions visualiser ceci en tant que diviser la liste de nombres en table avec 5 colonnes. Ceci ressemblerait à ceci :

 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 

Nous assortissons alors chaque colonne, qui nous donne

 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 

Une fois relus comme liste simple de nombres, nous obtenons à 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 . Ici, les 10 qui était toute la manière à l'extrémité, a déplacé toute la manière au commencement. Cette liste de l'autre côté est assortie using une sorte de 3 espaces, et puis 1 sorte d'espace (sorte d'insertion simple).

Gap ordonnancent

L'ordre d'espace de est une partie intégrale de l'algorithme de shellsort. N'importe quel ordre d'incrément fonctionnera, à condition que le dernier élément soit 1. L'algorithme commence en exécutant une sorte d'insertion d'espace de , avec l'espace étant le premier nombre dans l'ordre d'espace. Il continue à exécuter une sorte d'insertion d'espace pour chaque nombre dans l'ordre, jusqu'à ce qu'il finisse avec un espace de 1. Quand l'espace est 1, la sorte d'insertion d'espace est simplement une sorte d'insertion ordinaire , garantissant que la liste finale est assortie.

L'ordre d'espace qui a été à l'origine suggéré par le Donald Shell était de commencer par N/2 et de diviser en deux le nombre jusqu'à ce qu'il atteigne 1. Tandis que cet ordre fournit des perfectionnements significatifs d'exécution au-dessus des algorithmes quadratiques du tels que la sorte d'insertion , il peut être changé légèrement pour diminuer plus loin les temps de fonctionnement moyens et des cas les pires. Le manuel de Weiss démontre que cet ordre permet un O de pire cas (sorte de n^2), si les données sont au commencement dans la rangée comme (small_1, large_1, small_2, large_2,…) - c., la moitié supérieure des nombres sont placées, dans l'ordre assorti, dans même les endroits d'index et le bas de gamme des nombres sont placés pareillement dans les endroits répertoriés impairs.

Peut-être la propriété la plus cruciale de Shellsort est que les éléments demeurent k-assortis même pendant que l'espace diminue. Par exemple, si une liste était 5 assortis et puis 3 assortis, la liste est maintenant non seulement 3 assortis, mais 5 - et 3 assortis. Si ce n'étaient pas vrai, l'algorithme déferait le travail qu'il avait effectué dans des itérations précédentes, et ne réaliserait pas un si bas temps de fonctionnement.

Selon le choix de l'ordre d'espace, Shellsort a un temps de fonctionnement des cas les pires prouvé du O (n^2) (using les incréments de Shell qui commencent par 1/2 la taille de rangée et se divisent par 2 chaque fois), O (n^ {3/2}) (using les incréments de Hibbard de 2^k-1), O (n^ {4/3}) (using les incréments de Sedgewick de 9 (4^i) - 9 (2^i) + 1, ou 4^ {i+1} + 3 (2^i) + 1), ou O (n \ log^2 n), et probablement meilleurs temps de fonctionnement non fondés. L'existence d'un O (n \ exécution des cas les pires de la notation n) de Shellsort ont été exclus par Poonen, Plaxton, et Suel.

L'ordre le plus connu est 1, 4, 10, 23, 57, 132, 301, 701. Un tel Shell assortissent est plus rapide qu'une sorte d'insertion et une sorte de tas , mais si elle est plus rapide qu'un Quicksort pour de petites rangées (plus moins de 50 éléments), lui est plus lent pour de plus grandes rangées. Après 701, les lacunes dans le la progression que géométrique peut être calculée ont employé, comme : nextgap = rond (espace * 2.3)

Algorithme de sorte de Shell dans C/C++

Ce qui suit est une exécution de sorte de coquille écrite dans le C / C++ pour assortir un choix de nombres entiers. L'ordre d'incrément utilisé en ce code d'exemple donne un temps de fonctionnement des cas les pires du O (n2).

lang=c> de incrément, temp ; incrément = taille/2 ; tandis que (incrément > 0) {pour (I = incrément ; i < taille ; i++) {j = I ; temp = A ; tandis que (&& (d'incrément de >= de j) (A > temp)) {A = A - incrément ; j = j - incrément ; } A = temp ; } si (== d'incrément 2) incrément = 1 ; autrement incrément = (international) (incrément/2.2) ; } }

Algorithme de sorte de Shell dans Java

Une exécution de Java de sorte de Shell est comme suit : lang=java> de 0 ; incrément = (== 2 d'incrément ? 1 : (international) Math.2))) { pour (international i = incrément ; i < a.length ; i++) { pour (international j = I ; && a - incrément > a d'incrément de >= de j ; j - = incrément) { temp d'international = a ; a = a - incrément ; a - incrément = temp ; } } } }

Algorithme de sorte de Shell dans le python

lang=python> de pour l'incrément dans le new_increment (a) : pour I dans le xrange (l'incrément, len (a)) : pour j dans le xrange (I, increment-1, - incrément) : si a - incrément < a : coupure temp = a ; a = a - incrément a - incrément = temp renvoyer a

.

Random links:Ryukyu Robin | Flyswatter (album) | Cuvette de Poussin-fil-Un | Ronaldsay du nord | C.J. Cregg | Shell_clasifica