Tri Shell

Cet algorithme porte le nom de son auteur, Donald Shell, qui l'a publié en 1959. Son principe peut être vu comme une application de l'idée du CombSort (faire prendre des raccourcis aux éléments ayant beaucoup de chemin à faire) au tri par insertion (le CombSort est une variante du tri à bulle). Au lieu de comparer les valeurs adjacentes lors du tri par insertion, on compare des valeurs séparées par un écart plus grand. Plus l'écart est grand et plus les éléments sont déplacés rapidement vers leur position finale, mais aussi plus le déplacement est imprécis. Il faut donc appliquer l'algorithme avec une séquence d'écarts décroissante vers un. Ainsi, à la dernière étape quand l'écart vaut un, on applique l'algorithme de tri par insertion de base, mais sur un tableau déjà presque trié par les étapes précédentes.

Donald Shell propose d'utiliser lgr/2 comme première valeur de l'écartement, puis de le diviser par deux à chaque étape. Le pseudo-code est donc le suivant:

ecart=lgr/2
tant que ecart>0:
  appliquer l'algorithme de tri par insertion en comparant i-ecart et i, puis i-2ecart et i-ecart, puis i-3ecart et i-2ecart, etc.

Comme dans le cas du CombSort, la séquence des valeurs prises par l'écart se révèle être d'une importance capitale pour les performances du tri de Shell. Il existe des cas pathologiques qui font que la séquence que nous avons utilisée ici présente une complexité en O(n^2) dans le pire des cas. D'autres séquences ont été proposé: la séquence des incréments de Hibbard (2^k − 1) permet une complexité dans le pire des cas de O(n^(3/2)), les incréments de Pratt (2^i*3^j) permettent un pire cas en O(n log(n)log(n)). Ces résultats font du tri de Shell un candidat tout à fait valide pour des instances de tableau de quelques centaines de milliers d'éléments quand il est correctement implémenté.

Dans notre cas, les instances de tableaux que nous utilisons sont trop petites pour que ces optimisations présentent un réel avantage. Si on voulait le faire, il faudrait prendre en valeur initiale de l'écart la plus grande valeur de la suite utilisée, puis prendre les valeurs successives en descendant ensuite.

De façon intéressante, déterminer la meilleure séquence d'écart pour le shell sort s'avère être un problème de recherche de notre siècle en informatique. Par exemple, un article publié en 2001 propose la suite suivante, qui semble optimale en pratique pour des tailles de tableau allant jusqu'à 10^5: {1, 4, 10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th International Symposium on Fundamentals of Computation Theory, LNCS 2001; Vol. 2138).