AccueilđŸ‡«đŸ‡·Chercher

Tri de nombres entiers

En informatique, le tri de nombres entiers est le problĂšme algorithmique consistant Ă  trier une collection d'Ă©lĂ©ments au moyen de clĂ©s numĂ©riques, chacune Ă©tant un nombre entier. Les algorithmes conçus pour le tri des nombres entiers peuvent Ă©galement souvent ĂȘtre appliquĂ©s aux problĂšmes de tri dans lesquels les clĂ©s sont des nombres dĂ©cimaux, des nombres rationnels ou des chaĂźnes de texte[1]. La possibilitĂ© d'effectuer une arithmĂ©tique sur les clĂ©s permet aux algorithmes de tri d'entiers d'ĂȘtre plus rapides que les algorithmes de tri par comparaison, en fonction du dĂ©tail des opĂ©rations autorisĂ©es dans le modĂšle de calcul et de la taille des entiers Ă  trier.

Les algorithmes de tri de nombres entiers, notamment le tri pigeonhole, le tri comptage et le tri par base, sont largement utilisés et pratiques. D'autres algorithmes de tri de nombres entiers avec des limites de temps plus faibles dans le pire des cas ne sont pas considérés comme pratiques pour les architectures informatiques à 64 bits ou moins. Beaucoup de ces algorithmes sont connus, les performances dépendant du nombre d'éléments à trier, du nombre de bits par clé et du nombre de bits par mot de l'ordinateur exécutant l'algorithme de tri.

Considérations générales

La complexitĂ© temporelle des algorithmes de tri d’entiers dĂ©pend gĂ©nĂ©ralement de trois paramĂštres : le nombre n de valeurs Ă  trier, la magnitude K de la clĂ© la plus grande possible Ă  trier et le nombre w de bits pouvant ĂȘtre reprĂ©sentĂ©s dans un seul mot machine de l'ordinateur sur lequel l'algorithme doit ĂȘtre exĂ©cutĂ©. Typiquement, on suppose que w ≄ log2(max(n, K)) ; c'est-Ă -dire que les mots machine sont suffisamment grands pour reprĂ©senter un index dans la sĂ©quence de donnĂ©es d'entrĂ©e, et Ă©galement suffisamment grands pour reprĂ©senter une clĂ© unique[2].

Les algorithmes de tri de nombres entiers sont gĂ©nĂ©ralement conçus pour fonctionner soit dans la machine Ă  pointeur, soit dans la machine RAM. La principale diffĂ©rence entre ces deux modĂšles rĂ©side dans la maniĂšre dont la mĂ©moire peut ĂȘtre adressĂ©e. La machine RAM permet Ă  toute valeur stockĂ©e dans un registre d'ĂȘtre utilisĂ©e comme adresse des opĂ©rations de lecture et d'Ă©criture en mĂ©moire, avec un coĂ»t unitaire par opĂ©ration. Cette capacitĂ© permet Ă  certaines opĂ©rations complexes sur les donnĂ©es d'ĂȘtre rapidement mises en Ɠuvre Ă  l'aide de recherches dans les tables. En revanche, dans le modĂšle de pointeur, les opĂ©rations de lecture et d'Ă©criture utilisent les adresses stockĂ©es dans les pointeurs et il est interdit d'effectuer des opĂ©rations arithmĂ©tiques sur ces pointeurs. Dans les deux modĂšles, des valeurs de donnĂ©es peuvent ĂȘtre ajoutĂ©es et des opĂ©rations boolĂ©ennes au niveau du bit et des opĂ©rations de dĂ©calage binaire peuvent gĂ©nĂ©ralement Ă©galement ĂȘtre effectuĂ©es sur ces unitĂ©s, en unitĂ©s de temps par opĂ©ration. DiffĂ©rents algorithmes de tri de nombres entiers supposent diffĂ©rentes hypothĂšses, toutefois, quant Ă  savoir si la multiplication de nombres entiers est Ă©galement autorisĂ©e en tant qu'opĂ©ration temporelle[3]. D'autres modĂšles de calcul plus spĂ©cialisĂ©s, tels que la PRAM, ont Ă©galement Ă©tĂ© envisagĂ©s[4].

Andersson, Miltersen & Thorup (1999) ont montrĂ© que, dans certains cas, les multiplications ou les recherches dans les tables requises par certains algorithmes de tri d'entiers pourraient ĂȘtre remplacĂ©es par des opĂ©rations personnalisĂ©es qui seraient plus facilement implĂ©mentĂ©es dans le matĂ©riel, mais qui ne sont gĂ©nĂ©ralement pas disponibles sur des ordinateurs polyvalents. Thorup (2003) amĂ©liorĂ© ceci en montrant comment remplacer ces opĂ©rations spĂ©ciales par les instructions de manipulation de champs de bits dĂ©jĂ  disponibles sur les processeurs Pentium.

Tri par rapport aux files de priorité d'entiers

Une file de prioritĂ© est une structure de donnĂ©es permettant de gĂ©rer un ensemble d'Ă©lĂ©ments munis de prioritĂ©s numĂ©riques, comportant des opĂ©rations permettant de rechercher et de supprimer l'Ă©lĂ©ment ayant la valeur de prioritĂ© minimale. Les files de prioritĂ© basĂ©es sur la comparaison, telles que le tas binaire, prennent un temps logarithmique par mise Ă  jour, mais d'autres structures telles que l'arbre de van Emde Boas ou la file d'attente de compartiment peuvent ĂȘtre plus rapides pour les entrĂ©es dont les prioritĂ©s sont de petits entiers. Ces structures de donnĂ©es peuvent ĂȘtre utilisĂ©es dans l'algorithme de tri par sĂ©lection, qui trie une collection d'Ă©lĂ©ments en recherchant et en supprimant de maniĂšre rĂ©pĂ©tĂ©e le plus petit Ă©lĂ©ment de la collection et en renvoyant les Ă©lĂ©ments dans l'ordre dans lequel ils ont Ă©tĂ© trouvĂ©s. Une file de prioritĂ© peut ĂȘtre utilisĂ©e pour gĂ©rer la collection d'Ă©lĂ©ments dans cet algorithme, et le temps pour cet algorithme sur une collection de n Ă©lĂ©ments peut ĂȘtre limitĂ© par le temps nĂ©cessaire pour initialiser la file de prioritĂ©, puis pour effectuer n opĂ©rations de recherche et suppression. Par exemple, l'utilisation d'un tas binaire comme file de prioritĂ© dans le tri par sĂ©lection conduit Ă  l'algorithme de tri par tas, un algorithme de tri de comparaison de complexitĂ© temporelle en O(n log n) . Au lieu de cela, l’utilisation du tri par sĂ©lection avec une file d’attente donne une forme de tri par casier et l’utilisation d’arbres de Van Emde Boas ou d’autres files d’attente avec prioritĂ© entiĂšre conduit Ă  d’autres algorithmes de tri d’entiers rapides. [5]

Au lieu d'utiliser une file de prioritĂ© d'entiers dans un algorithme de tri, il est possible d'aller dans la direction opposĂ©e et d'utiliser les tris d'entiers comme sous-routine dans une structure de donnĂ©es de file de prioritĂ© d'entiers. Thorup (2007) a utilisĂ© cette idĂ©e pour montrer que, s'il est possible de rĂ©aliser le tri d'entiers en temps linĂ©aire par clĂ© alors cette mĂȘme complexitĂ© s'applique aux opĂ©rations d'insertion et de suppression dans une file de prioritĂ©. La rĂ©duction de Thorup est complexe et s’appuie cependant sur l'existence d'une multiplication rapide ou d'une recherche rapide dans une table mais il donne une file de prioritĂ© alternative utilisant l'addition et les opĂ©rations sur les boolĂ©ens en temps T(n) + T(log n) + T(log log n) + ... par opĂ©ration, multipliant au plus le temps par un logarithme itĂ©rĂ©.[5]

Utilisabilité

Les algorithmes classiques de tri des nombres entiers de type tri pigeonhole, tri comptage et tri par base sont largement utilisés et pratiques[6]. La plupart des recherches ultérieures sur les algorithmes de tri de nombres entiers ont été moins axées sur l'aspect pratique que sur les améliorations théoriques apportées à leur analyse des pires cas, et les algorithmes issus de cette ligne de recherche ne sont apparemment pas pratiques pour les architectures informatiques 64 bits actuelles, bien que des expériences ont montré que certaines de ces méthodes peuvent constituer une amélioration du tri de base pour les données de 128 bits ou plus par clé[6]. De plus, pour les grands ensembles de données, le modÚle d'accÚs mémoire quasi aléatoire de nombreux algorithmes de tri d'entiers peuvent les handicaper par rapport aux algorithmes de tri de comparaison conçus pour la hiérarchie de mémoire[7].

Le tri de nombres entiers constitue l’un des six tests de performances en mathĂ©matiques discrĂštes de systĂšmes de calcul Ă  haute productivitĂ© DARPA [8] et l’un des onze points de repĂšre de la suite de tests de performances NAS .

Algorithmes pratiques

Le tri pigeonhole et le tri comptage peuvent tous les deux trier n Ă©lĂ©ments de donnĂ©es dont les clĂ©s sont comprises entre 0 et K − 1 dans le temps O(n + K) . Dans le tri pigeonhole, les pointeurs vers les Ă©lĂ©ments de donnĂ©es sont distribuĂ©s dans une table de compartiments, reprĂ©sentĂ©s comme des types de donnĂ©es de collection tels que des listes chaĂźnĂ©es, en utilisant les clĂ©s comme indices dans la table. Ensuite, tous les compartiments sont concatĂ©nĂ©s ensemble pour former la liste de sortie[9]. Le tri comptage utilise une table de compteurs Ă  la place d'une table de compartiments, pour dĂ©terminer le nombre d'articles avec chaque clĂ©. Ensuite, un calcul de somme de prĂ©fixes est utilisĂ© pour dĂ©terminer la plage de positions dans la sortie triĂ©e Ă  laquelle les valeurs de chaque clĂ© doivent ĂȘtre placĂ©es. Enfin, lors d'un deuxiĂšme passage sur l'entrĂ©e, chaque Ă©lĂ©ment est dĂ©placĂ© Ă  la position de sa clĂ© dans le tableau de sortie[10]. Les deux algorithmes n'impliquent que de simples boucles sur les donnĂ©es d'entrĂ©e (prenant le temps O(n) ) et sur l'ensemble des clĂ©s possibles (prenant le temps O(K) ), donnant leur complexitĂ© temporelle en O(n + K) .

Le tri par base est un algorithme de tri qui fonctionne pour des clĂ©s plus grandes que le tri pigeonhole ou le tri comptage en effectuant plusieurs parcours des donnĂ©es. Chaque parcours trie l'entrĂ©e en utilisant uniquement une partie des clĂ©s, en utilisant un algorithme de tri diffĂ©rent (tel que le tri pigeonhole ou le tri de comptage) qui ne convient qu'aux petites clĂ©s. Pour diviser les clĂ©s en parties, l'algorithme de tri par base calcule la notation positionnelle pour chaque clĂ©, en fonction de certaines bases choisies; ensuite, la partie de la clĂ© utilisĂ©e pour la i Ăšme passe de l'algorithme est le i Ăšme chiffre dans la notation positionnelle pour la clĂ© complĂšte, en partant du chiffre le moins significatif et en progressant vers le plus significatif. Pour que cet algorithme fonctionne correctement, l'algorithme de tri utilisĂ© Ă  chaque parcours des donnĂ©es doit ĂȘtre stable : les Ă©lĂ©ments avec des chiffres Ă©gaux ne doivent pas changer de position les uns avec les autres. Pour une plus grande efficacitĂ©, la base doit ĂȘtre choisie pour ĂȘtre proche du nombre d'Ă©lĂ©ments de donnĂ©es, n . De plus, l'utilisation d'une puissance de deux prĂšs de n comme base permet de calculer rapidement les clĂ©s de chaque parcours en utilisant uniquement des opĂ©rations rapides de dĂ©calage binaire et de masque. Avec ces choix, et avec le tri pigeonhole ou le tri par comptage comme algorithme de base, l'algorithme de tri par base peut trier n Ă©lĂ©ments de donnĂ©es ayant des clĂ©s dans la plage de 0 Ă  K − 1 dans le temps O(n logn K)[11].

Algorithmes théoriques

De nombreux algorithmes de tri d'entiers ont été développés dont l'analyse théorique montre qu'ils se comportent mieux que le tri par comparaison, le tri pigeonhole ou le tri par base pour des combinaisons suffisamment grandes de paramÚtres définissant le nombre d'éléments à trier, la plage de clés et la taille du mot machine. La performance d'un algorithme dépend des valeurs de ces paramÚtres. Cependant, malgré leurs avantages théoriques, ces algorithmes ne sont pas une amélioration pour les plages typiques de ces paramÚtres qui se posent dans des problÚmes de tri pratiques.

Algorithmes pour les petites clés

Un arbre de Van Emde Boas peut ĂȘtre utilisĂ© comme file de prioritĂ© pour trier un ensemble de n clĂ©s, chacune dans la plage de 0 Ă  K − 1, dans le temps O(n log log K) . Il s'agit d'une amĂ©lioration thĂ©orique par rapport au tri par base lorsque K est suffisamment grand. Cependant, pour utiliser un arbre de Van Emde Boas, il faut soit une mĂ©moire directement accessible de K mots, soit il faut la simuler Ă  l'aide d'une table de hachage, en rĂ©duisant l'espace Ă  une structure linĂ©aire mais en rendant l'algorithme alĂ©atoire.

Kirkpatrick & Reisch (1984) ont dĂ©veloppĂ© une technique plus sophistiquĂ©e, assez similaire et avec de meilleures performances thĂ©oriques. Ils ont observĂ© que chaque lecture des donnĂ©es dans le tri par base peut ĂȘtre interprĂ©tĂ©e comme une technique de rĂ©duction de plage qui, en temps linĂ©aire, rĂ©duit la taille de clĂ© maximale d'un facteur de n ; au lieu de cela, leur technique rĂ©duit la taille de la clĂ© Ă  la racine carrĂ©e de sa valeur prĂ©cĂ©dente (divisant par deux le nombre de bits nĂ©cessaires pour reprĂ©senter une clĂ©), toujours en temps linĂ©aire. Comme dans le tri par base, ils interprĂštent les clĂ©s comme des nombres en base b de 2 chiffres pour une valeur de b qui est approximativement √K Ils regroupent ensuite les Ă©lĂ©ments Ă  trier en compartiments en fonction de leurs chiffres Ă©levĂ©s, en temps linĂ©aire, Ă  l'aide d'une grande mĂ©moire directement accessible mais non initialisĂ©e ou d'une table de hachage. Chaque compartiment a un reprĂ©sentant, l'article dans le compartiment avec la plus grande clĂ©; ils trient ensuite la liste des Ă©lĂ©ments en utilisant comme clĂ©s les chiffres hauts pour les reprĂ©sentants et les chiffres bas pour les non-reprĂ©sentants. En regroupant Ă  nouveau les Ă©lĂ©ments de cette liste dans des compartiments, chaque compartiment peut ĂȘtre placĂ© dans un ordre triĂ©, et en extrayant les reprĂ©sentants de la liste triĂ©e, les compartiments peuvent ĂȘtre concatĂ©nĂ©s ensemble dans un ordre triĂ©. Ainsi, en temps linĂ©aire, le problĂšme de tri est rĂ©duit Ă  un autre problĂšme de tri rĂ©cursif dans lequel les clĂ©s sont beaucoup plus petites, la racine carrĂ©e de leur amplitude prĂ©cĂ©dente. La rĂ©pĂ©tition de cette rĂ©duction de plage jusqu'Ă  ce que les clĂ©s soient suffisamment petites pour trier le compartiment conduit Ă  un algorithme avec le temps d'exĂ©cution O(n log logn K) .

Un algorithme alĂ©atoire compliquĂ© de Han & Thorup (2002) dans le modĂšle de calcul "RAM de mots" permet de rĂ©duire encore plus ces limites de temps, Ă  O(n√log log K) .

Algorithmes pour les grands mots

Un algorithme de tri d'entiers est dit non conservateur s'il nĂ©cessite une taille de mot w qui est significativement plus grande que log max(n, K)[12]. Un exemple extrĂȘme, si w ≄ K, et que toutes les clĂ©s sont distinctes, alors l'ensemble des clĂ©s peut ĂȘtre triĂ© en temps linĂ©aire en le reprĂ©sentant comme un tableau de bits, avec un bit Ă  la position i lorsque i est l'une des clĂ©s d'entrĂ©e, puis en supprimant Ă  plusieurs reprises le bit le moins significatif[13].

L'algorithme de tri condensĂ© non conservateur d' Albers & Hagerup (1997) utilise un sous-programme, basĂ© sur le tri bitonique de Ken Batcher, pour fusionner deux sĂ©quences de clĂ©s triĂ©es suffisamment courtes pour ĂȘtre regroupĂ©es dans un seul mot machine. L'entrĂ©e de l'algorithme de tri condensĂ©s, une sĂ©quence d'articles stockĂ©s un par mot, est transformĂ©e en une forme condensĂ©s, une sĂ©quence de mots contenant chacun plusieurs Ă©lĂ©ments dans un ordre triĂ© ; en utilisant ce sous-programme Ă  plusieurs reprises pour doubler le nombre d'Ă©lĂ©ments condensĂ©s dans chacun mot. Une fois la sĂ©quence sous forme compactĂ©e, Albers et Hagerup utilisent une forme de tri fusion pour la trier. Lorsque deux sĂ©quences sont fusionnĂ©es pour former une seule sĂ©quence plus longue, le mĂȘme sous-programme de tri bitonique peut ĂȘtre utilisĂ© pour extraire Ă  plusieurs reprises des mots condensĂ©s constituĂ©s des plus petits Ă©lĂ©ments restants des deux sĂ©quences. Cet algorithme gagne suffisamment d'accĂ©lĂ©ration de sa reprĂ©sentation condensĂ©e pour trier son entrĂ©e en temps linĂ©aire chaque fois qu'il est possible qu'un seul mot contienne des clĂ©s Ω(log n log log n) ; c'est-Ă -dire, lorsque log K log n log log n ≀ cw pour une constante c > 0 .

Algorithmes pour quelques éléments

Le tri pigeonhole, le tri par comptage, le tri par base et le tri par arbre Van Emde Boas fonctionnent tous mieux lorsque la taille de la clé est petite; pour les clés suffisamment grandes, elles deviennent plus lentes que les algorithmes de tri comparatif. Cependant, lorsque la taille de la clé ou la taille du mot est trÚs grande par rapport au nombre d'éléments (ou de maniÚre équivalente lorsque le nombre d'éléments est petit), il peut de nouveau devenir possible de trier rapidement, en utilisant différents algorithmes qui tirent parti du parallélisme inhérent dans la capacité d'effectuer des opérations arithmétiques sur de gros mots.

Un premier rĂ©sultat dans cette direction a Ă©tĂ© fourni par Ajtai, Fredman & KomlĂłs (1984) en utilisant le modĂšle de calcul Ă  sonde cellulaire (un modĂšle artificiel dans lequel la complexitĂ© d'un algorithme n'est mesurĂ©e que par le nombre d'accĂšs Ă  la mĂ©moire qu'il effectue). S'appuyant sur leurs travaux, Fredman & Willard (1994) ont dĂ©crit deux structures de donnĂ©es, le tas Q et le tas atomique, qui peuvent ĂȘtre implĂ©mentĂ©es sur une machine Ă  accĂšs alĂ©atoire. Le segment Q est une version bit parallĂšle d'un tri binaire, et permet Ă  la fois des opĂ©rations de file de prioritĂ© et des requĂȘtes de successeur et prĂ©dĂ©cesseur Ă  effectuer en temps constant pour des ensembles d'Ă©lĂ©ments de taille O((log N)1/4), oĂč N ≀ 2w est la taille des tables prĂ©calculĂ©es nĂ©cessaires pour implĂ©menter la structure de donnĂ©es. Le tas atomique est un B-arbre dans lequel chaque nƓud d'arbre est reprĂ©sentĂ© comme un tas Q; il permet des opĂ©rations de file de prioritĂ© en temps constant (et donc un tri) pour des ensembles d'Ă©lĂ©ments de taille (log N)O(1) .

Andersson et al. (1998) fournissent un algorithme alĂ©atoire appelĂ© tri par signature qui permet un tri linĂ©aire dans le temps d'ensembles jusqu'Ă  2O((log w)1/2 − Δ) Ă©lĂ©ments Ă  la fois, pour toute constante Δ > 0 . Comme dans l'algorithme de Kirkpatrick et Reisch, ils effectuent une rĂ©duction de plage en utilisant une reprĂ©sentation des clĂ©s sous forme de nombres dans la base b pour un choix judicieux de b . Leur algorithme de rĂ©duction de plage remplace chaque chiffre par une signature, qui est une valeur hachĂ©e avec O(log n) bits de sorte que diffĂ©rentes valeurs de chiffre ont des signatures diffĂ©rentes. Si n est suffisamment petit, les nombres formĂ©s par ce processus de remplacement seront significativement plus petits que les clĂ©s d'origine, permettant Ă  l'algorithme de tri condensĂ© non conservateur d' Albers & Hagerup (1997) de trier les nombres remplacĂ©s en temps linĂ©aire. À partir de la liste triĂ©e des nombres remplacĂ©s, il est possible de former un tri condensĂ© des clĂ©s en temps linĂ©aire, et les enfants de chaque nƓud du tri peuvent ĂȘtre triĂ©s rĂ©cursivement en utilisant uniquement des clĂ©s de taille b, aprĂšs quoi un parcours d'arbre produit l'ordre triĂ© des articles.

Algorithmes trans-dichotomiques

Fredman & Willard (1993) ont prĂ©sentĂ© le modĂšle d'analyse transdichotomique pour les algorithmes de tri d'entiers, dans lequel rien n'est supposĂ© sur la plage des clĂ©s entiĂšres et il faut limiter les performances de l'algorithme en fonction du nombre de valeurs de donnĂ©es uniquement. Alternativement, dans ce modĂšle, le temps d'exĂ©cution d'un algorithme sur un ensemble de n Ă©lĂ©ments est supposĂ© ĂȘtre le temps d'exĂ©cution du pire cas pour toute combinaison possible de valeurs de K et w . Le premier algorithme de ce type Ă©tait l'algorithme de tri des arbres de fusion de Fredman et Willard, qui s'exĂ©cute dans le temps O(n log n / log log n) ; il s'agit d'une amĂ©lioration par rapport au tri par comparaison pour tout choix de K et w . Une version alternative de leur algorithme qui inclut l'utilisation de nombres alĂ©atoires et d'opĂ©rations de division entiĂšre amĂ©liore cela Ă  O(n√log n) .

Depuis leur travail, des algorithmes encore meilleurs ont Ă©tĂ© dĂ©veloppĂ©s. Par exemple, en appliquant Ă  plusieurs reprises la technique de rĂ©duction de la plage Kirkpatrick - Reisch jusqu'Ă  ce que les clĂ©s soient suffisamment petites pour appliquer l'algorithme de tri condensĂ© Albers – Hagerup, il est possible de trier dans le temps O(n log log n) ; cependant, la partie rĂ©duction de plage de cet algorithme nĂ©cessite soit une grande mĂ©moire (proportionnelle Ă  √K ), soit une randomisation sous forme de tables de hachage[14].

Han & Thorup (2002) ont montrĂ© comment trier en temps alĂ©atoire O(n√log log n) . Leur technique consiste Ă  utiliser des idĂ©es liĂ©es au tri des signatures pour partitionner les donnĂ©es en de nombreuses petites sous-listes, d'une taille suffisamment petite pour que le tri des signatures puisse trier chacune d'elles efficacement. Il est Ă©galement possible d'utiliser des idĂ©es similaires pour trier les entiers de maniĂšre dĂ©terministe dans le temps O(n log log n) et en mĂ©moire linĂ©aire[15]. En utilisant uniquement des opĂ©rations arithmĂ©tiques simples (pas de multiplications ou de recherches de table), il est possible de trier dans le temps alĂ©atoire attendu O(n log log n) [16] ou de maniĂšre dĂ©terministe dans le temps O(n (log log n)1 + Δ) pour toute constante Δ > 0 .

Références

Notes de bas de page
  1. Han & Thorup (2002)
  2. Fredman & Willard (1993)
  3. La question de savoir si une multiplication d'entiers ou si consulter un tableau revient sont permis revient Ă  Fredman & Willard (1993); voir Ă©galement Andersson, Miltersen & Thorup (1999).
  4. Reif (1985); commentaire dans Cole & Vishkin (1986); Hagerup (1987); Bhatt et al. (1991); Albers & Hagerup (1997).
  5. Chowdhury (2008).
  6. McIlroy, Bostic & McIlroy (1993); Andersson & Nilsson (1998).
  7. Rahman & Raman (1998).

  8. DARPA HPCS Discrete Mathematics Benchmarks, Duncan A. Buell, Université de Caroline du Sud (2011).
  9. Goodrich & Tamassia (2002). MĂȘme si Cormen et al. (2001) a aussi Ă©tabli une version de cet algorithme, la version qu'ils dĂ©crivent est adaptĂ©e aux entrĂ©es dont les clĂ©s sont des nombres rĂ©els plutĂŽt que seulement des entiers.
  10. Cormen et al. (2001), 8.2 Counting Sort, p. 168–169.
  11. Comrie (1929–1930); Cormen et al. (2001), 8.3 Radix Sort, p. 170–173.
  12. Kirkpatrick & Reisch (1984); Albers & Hagerup (1997).
  13. Kirkpatrick & Reisch (1984)
  14. Andersson et al. (1998).
  15. Han (2004).
  16. Thorup (2002)
Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplĂ©mentaires peuvent s’appliquer aux fichiers multimĂ©dias.