J'essaie de comprendre les différences entre le tri par insertion et le tri par sélection.
Ils semblent tous les deux avoir deux composants: une liste non triée et une liste triée. Ils semblent tous les deux prendre un élément de la liste non triée et le placer dans la liste triée au bon endroit. J'ai vu certains sites/livres dire que le tri par sélection le fait en échangeant un à un, tandis que le tri par insertion trouve simplement le bon endroit et l'insère. Cependant, j'ai vu d'autres articles dire quelque chose, disant que le type d'insertion échangeait également. Par conséquent, je suis confus. Y a-t-il une source canonique?
À partir d’une liste, prenez l’élément actuel et échangez-le avec le plus petit élément situé à droite de l’élément actuel.
À partir d’une liste, prenez l’élément actuel et insérez-le à l’emplacement approprié de la liste, en ajustant la liste à chaque insertion. Cela revient à organiser les cartes dans un jeu de cartes.
La complexité temporelle du tri de sélection est toujours n(n - 1)/2
, alors que le tri par insertion présente une meilleure complexité temporelle, car sa complexité la plus défavorable est n(n - 1)/2
. Généralement, il faudra des comparaisons inférieures ou égales à n(n - 1)/2
.
Source: http://cheetahonfire.blogspot.com/2009/05/selection-sort-vs-insertion-sort.html
Le tri par insertion et le tri par sélection ont tous deux une boucle externe (sur chaque index) et une boucle interne (sur un sous-ensemble d'index). Chaque passage de la boucle interne étend la région triée d'un élément, aux dépens de la région non triée, jusqu'à épuisement des éléments non triés.
La différence réside dans ce que fait la boucle intérieure:
Dans le tri par sélection, la boucle interne passe sur les éléments non triés. Chaque passe sélectionne un élément et le déplace vers son emplacement final (à la fin de la région triée).
Dans le tri par insertion, chaque passage de la boucle interne itère sur les éléments triés. Les éléments triés sont déplacés jusqu'à ce que la boucle trouve le bon endroit pour insérer le prochain élément non trié.
Ainsi, dans un tri par sélection, les éléments triés sont trouvés dans l'ordre de sortie et restent en place une fois qu'ils sont trouvés. Inversement, dans un tri par insertion, les éléments non triés restent en place jusqu'à ce qu'ils soient consommés dans l'ordre d'entrée, tandis que les éléments de la région triée continuent à être déplacés.
En ce qui concerne la permutation: le tri par sélection effectue une permutation par passe de la boucle interne. Le tri par insertion enregistre généralement l'élément à insérer sous la forme temp
before la boucle interne, laissant ainsi la place à la boucle interne de décaler les éléments triés d'un cran, puis copie temp
vers le point d'insertion après.
Il est possible que la confusion soit due au fait que vous comparez une description du tri d'un liste liée avec une description du tri d'un tablea. Mais je ne peux pas en être sûr, puisque vous n'avez pas cité vos sources.
Le moyen le plus simple de comprendre les algorithmes de tri consiste souvent à obtenir une description détaillée de l’algorithme (et non des mots vagues tels que "ce type utilise swap. Quelque part. Je ne dis pas où"), obtenir des cartes à jouer (5 à 10 devrait suffire pour des algorithmes de tri simples) et exécutez l’algorithme à la main.
Tri de sélection: parcourez les données non triées à la recherche du plus petit élément restant, puis échangez-les à la position qui suit immédiatement les données triées. Répétez jusqu'à la fin. Si vous triez une liste, vous n'avez pas besoin de permuter le plus petit élément en position, vous pouvez plutôt retirer le nœud de liste de son ancienne position et l'insérer à la nouvelle.
Tri par insertion: prenez l'élément immédiatement après les données triées, parcourez les données triées pour trouver l'emplacement où le placer et placez-le à cet endroit. Répétez jusqu'à la fin.
Le tri par insertion peut utilise le swap pendant sa phase "d'analyse", mais ce n'est pas obligatoire et ce n'est pas le moyen le plus efficace sauf si vous triez un tableau d'un type de données qui: (a) ne peut pas être déplacé , seulement copié ou échangé; et (b) est plus coûteux à copier qu'à échanger. Si le tri par insertion utilise le swap, son fonctionnement consiste à rechercher simultanément le lieu et y placer le nouvel élément, en échangeant de manière répétée le nouvel élément avec l'élément juste avant, tant que l'élément avant qu'il ne soit plus gros que lui. Une fois que vous atteignez un élément qui n’est pas plus gros, vous avez trouvé le bon emplacement et vous passez au nouvel élément suivant.
TRI DE SELECTION
Supposons qu'il y ait un tableau de nombres écrits de manière particulière/aléatoire et disons que nous devons arranger dans un ordre croissant. Alors, prenez un nombre à la fois et remplacez-les par le plus petit no. disponible dans la liste. en faisant cette étape, nous obtiendrons finalement le résultat souhaité.
INSERTION SORT
En gardant à l’esprit la même hypothèse, la seule différence est que, cette fois, nous sélectionnons un nombre à la fois et nous l’insérons dans la partie présélectionnée, ce qui réduit les comparaisons et est donc plus efficace.
La logique des deux algorithmes est assez similaire. Ils ont tous deux un sous-tableau partiellement trié au début du tableau. La seule différence est la façon dont ils recherchent le prochain élément à placer dans le tableau trié.
tri par insertion: insère l'élément suivant à la position correcte;
Tri de la sélection: sélectionne le plus petit élément et l'échange avec l'élément en cours.
En outre, tri par insertion est stable, contrairement à tri par sélection.
J'ai implémenté les deux en python, et il est intéressant de noter leur similitude:
def insertion(data):
data_size = len(data)
current = 1
while current < data_size:
for i in range(current):
if data[current] < data[i]:
temp = data[i]
data[i] = data[current]
data[current] = temp
current += 1
return data
Avec un petit changement, il est possible de faire l'algorithme de tri par sélection.
def selection(data):
data_size = len(data)
current = 0
while current < data_size:
for i in range(current, data_size):
if data[i] < data[current]:
temp = data[i]
data[i] = data[current]
data[current] = temp
current += 1
return data
En bref,
Selection sort: Sélectionnez le premier élément d'un tableau non trié et comparez-le avec les éléments non triés restants. Il est similaire au tri Bubble, mais au lieu d’échanger chacun des éléments plus petits, conserve le plus petit index d’éléments mis à jour et échangez-le à la fin de chaque boucle .
Tri d'insertion: Il est opposé au tri de sélection où il sélectionne le premier élément d'un sous-tableau non trié et le compare au sous-tableau trié et insère le plus petit élément trouvé et déplacez tous les éléments triés de sa droite vers le premier élément non trié.
En un mot, je pense que le tri par sélection recherche d'abord la plus petite valeur du tableau, puis effectue le swap, tandis que le tri par insertion prend une valeur et la compare à chaque valeur qui lui reste (derrière lui). Si la valeur est inférieure, il est échangé. Ensuite, la même valeur est comparée à nouveau et si elle est inférieure à celle située derrière, elle est à nouveau permutée. J'espère que cela à du sens!
Je vais essayer encore une fois: considérez ce qui se passe dans le cas chanceux d'un tableau presque trié.
Lors du tri, le tableau peut être considéré comme ayant deux parties: côté gauche - trié, côté droit - non trié.
Tri par insertion - choisissez le premier élément non trié et essayez de lui trouver une place dans la partie déjà triée. Puisque vous effectuez une recherche de droite à gauche, il se peut très bien que le premier élément trié auquel vous comparez (le plus grand, le plus à droite dans la partie gauche) soit plus petit que l’élément sélectionné afin que vous puissiez passer immédiatement au prochain élément non trié.
Choix de tri - choisissez le premier élément non trié et essayez de trouver le plus petit élément de la partie non triée dans son ensemble, et échangez-les si nécessaire. Le problème est que, puisque la partie droite n'est pas triée, il faut penser chaque élément à chaque fois, car il est impossible de savoir s'il existe ou non un élément encore plus petit que l'élément sélectionné.
Btw., C'est exactement ce que heapsort améliore le tri par sélection - il est capable de trouver le plus petit élément beaucoup plus rapidement grâce au heap .
Tri de sélection: lorsque vous commencez à créer la sous-liste triée, l'algorithme garantit que la sous-liste triée est toujours entièrement triée, non seulement en fonction de ses propres éléments, mais également en termes de tableau complet, à savoir les sous-listes triées et non triées. Ainsi, le nouvel élément le plus petit une fois trouvé dans la sous-liste non triée serait simplement ajouté à la fin de la sous-liste triée.
Tri d'insertion: L'algorithme divise à nouveau le tableau en deux parties, mais ici l'élément est sélectionné dans la deuxième partie et inséré à la position correcte par rapport à la première partie. Cela ne garantit jamais que la première partie est triée en fonction du tableau complet, bien que lors du passage final, chaque élément se trouve à sa position correcte de tri.
La boucle interne du tri d'insertion passe par les éléments déjà triés (contrairement au tri de sélection). Cela lui permet de abandonner la boucle interne lorsque la bonne position est trouvée. Ce qui signifie que:
Le tri de sélection devra toujours passer par tous les éléments de la boucle interne. C’est pourquoi le tri par insertion est préféré au tri par sélection. Par contre, le type de sélection effectue beaucoup moins d’échanges d’éléments, ce qui peut être plus important dans certains cas.
Les deux algorithmes fonctionnent généralement comme ceci
Étape 1: prenez le prochain élément non trié de la liste non triée puis
Étape 2: placez-le au bon endroit dans la liste triée.
L'une des étapes est plus facile pour un algorithme et inversement.
Tri par insertion: Nous prenons le premier élément de la liste non triée, le plaçons dans la liste triée, quelque part . Nous savons où prendre l'élément suivant (la première position de la liste non triée), mais il faut encore du travail pour trouver où le placer ( quelque part ) . L'étape 1 est facile.
Tri de la sélection: Nous prenons l'élément quelque part de la liste non triée, puis le mettons à la dernière position de la liste triée. Nous devons trouver l’élément suivant (il est fort probable que ce n’est pas dans la première position de la liste non triée, mais plutôt quelque part ), puis le mettre à l’endroit la fin de la liste triée. L'étape 2 est facile
Fondamentalement, le tri par insertion consiste à comparer deux éléments à la fois et le tri par sélection sélectionne l'élément minimum dans l'ensemble du tableau et le trie.
Conceptuellement, le tri par insertion continue à trier la sous-liste en comparant deux éléments jusqu'à ce que tout le tableau soit trié, tandis que le tri par sélection sélectionne l'élément minimum et le remplace par le premier élément deuxième minimum, le deuxième élément, etc.
Le tri par insertion peut être affiché comme suit:
for(i=1;i<n;i++)
for(j=i;j>0;j--)
if(arr[j]<arr[j-1])
temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
Le tri de sélection peut être affiché comme suit:
for(i=0;i<n;i++)
min=i;
for(j=i+1;j<n;j++)
if(arr[j]<arr[min])
min=j;
temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
Une explication simple pourrait être comme ci-dessous:
Given: Tableau ou liste de nombres non triés.
Énoncé du problème: Pour trier la liste/le tableau de nombres par ordre croissant afin de comprendre la différence entre le tri par sélection et le tri par insertion.
Tri par insertion: Vous voyez la liste de haut en bas pour une compréhension plus facile. Nous considérons le premier élément comme notre valeur minimale initiale. Maintenant, l’idée est de parcourir linéairement chaque index de cette liste/de ce tableau pour déterminer s’il existe un autre élément à un index quelconque ayant une valeur inférieure à la valeur minimale initiale. Si nous trouvons une telle valeur, nous échangeons simplement les valeurs à leurs index, c'est-à-dire, disons que 15 était la valeur initiale minimale à l'indice 1 et que, lors du parcours linéaire des index, nous rencontrons un nombre de valeur inférieure, par exemple 7 à l'indice 9. Maintenant, cette valeur 7 à l’indice 9 est permutée avec l’indice 1 ayant une valeur de 15. Cette traversée continuera à faire la comparaison avec la valeur de l'index en cours avec les index restants à échanger pour la valeur la plus petite. Cela continue jusqu'au dernier dernier index de la liste/du tableau, car le dernier index est déjà trié et n'a pas de valeur à vérifier avec en dehors du tableau/de la liste.
Selection Sort: Supposons que le premier élément d'index de la liste/du tableau soit trié. Maintenant, à partir de l'élément situé au deuxième index, comparons-le à son index précédent pour voir si la valeur est plus petite. La traversée peut être visualisée en deux parties, triées et non triées. On pourrait visualiser un contrôle de comparaison du non trié vers le trié pour un index donné dans la liste/le tableau. Supposons que vous avez la valeur 19 à l’indice 1 et la valeur 10 à l’indice 3. Nous considérons le parcours du non trié au trié, c’est-à-dire de droite à gauche. Alors, disons que nous devons trier à l'indice 3. Nous voyons qu'il a une valeur inférieure à celle de l'indice 1 lorsque nous avons comparé de droite à gauche. Une fois identifié, il suffit de placer le nombre 10 de l’indice 3 à la place de l’indice 1 ayant la valeur 19. La valeur initiale 19 de l’indice 1 est décalée d’une place vers la droite. Cette traversée continue pour chaque élément de la liste/du tableau jusqu'au dernier élément.
Je n'ai ajouté aucun code car la question semble être de comprendre le concept de la méthode de parcours.
Le tri par insertion n'échange pas les choses. Même si elle utilise une variable temp, le point essentiel de l'utilisation de temp var est que lorsque nous avons trouvé qu'une valeur à un index était inférieure à la valeur de son index précédent, nous avons déplacé la valeur la plus élevée à la place des valeurs inférieures. index qui serait sur écrire des choses. Ensuite, nous utilisons la variable temp à substituer à l’index précédent. Exemple: 10, 20, 30, 50, 40. itération 1: 10, 20, 30, 50, 50. [temp = 40] itération 2: 10,20, 30, 40 (la valeur de temp), 50. Donc, nous insérez simplement une valeur à la position désirée à partir d’une variable.
Mais quand nous considérons le tri par sélection, nous trouvons d’abord l’indice ayant une valeur inférieure et échangeons cette valeur avec la valeur du premier index et continuons à échanger de façon répétée jusqu’à ce que tous les index soient triés. Ceci est identique à l’échange traditionnel de deux nombres. Exemple: 30, 20, 10, 40, 50. Itération 1: 10, 20, 30, 40, 50. Ici, temp var est utilisé exclusivement pour la permutation.