Un moyen efficace de compter le nombre de swaps à insérer trie un tableau d'entiers dans un ordre croissant
Donné un tableau de valeurs de longueur n, il est un moyen de compter le nombre de swaps, qui serait effectuée par l'insertion de tri pour trier ce tableau dans le temps de mieux que O(n2)?
Par exemple :
arr[]={2 ,1, 3, 1, 2}; //Answer is 4.
Algorithme:
for i <- 2 to N
j <- i
while j > 1 and a[j] < a[j - 1]
swap a[j] and a[j - 1] //I want to count this swaps?
j <- j - 1
source d'informationauteur Anil Kumar Arya
Vous devez vous connecter pour publier un commentaire.
Si vous voulez compter le nombre d'échanges nécessaires dans le tri par insertion, alors vous voulez trouver le numéro suivant: pour chaque élément, le nombre d'éléments inn le tableau sont plus petites que? La somme de ces valeurs est alors le nombre total de permutations.
Pour trouver le numéro, vous pouvez utiliser une commande de statistique de l'arbre, l'équilibre binaire un arbre de recherche qui peut efficacement vous dire combien d'éléments dans l'arbre sont plus petites que certains élément donné. Plus précisément, une orde de statistique de l'arbre prend en charge O(log n) insertion, suppression, recherche, et le nombre d'éléments dans l'arbre, à moins de quelque valeur. Vous pouvez alors compter le nombre de swaps sera effectuée comme suit:
Ce n'est O(n) itérations d'une boucle qui prend O(log n) le temps, de sorte que le total des travaux est de O(n log n), qui est plus rapide que la force brute approche.
Si vous voulez compter le nombre de swaps de tri de la sélection, vous pouvez utiliser le fait que le tri par insertion ne procédera à un échange sur la kième passer si, après le traitement de la première k-1 éléments de la liste, l'élément en position k n'est pas la k-ième plus petit élément. Si vous pouvez faire cela efficacement, nous avons alors le suivant de la base de l'esquisse d'un algorithme:
Alors, comment pouvons-nous mettre en œuvre de manière efficace? Il nous faut mieux être en mesure de vérifier si l'élément à un index donné est le bon élément, et doivent également efficace de trouver la position de l'élément qui appartient vraiment à un index donné le contraire. Pour ce faire, commencez par en créer un équilibre binaire un arbre de recherche qui fait correspondre à chaque élément de sa position dans le tableau d'origine. Cela prend du temps O(n log n). Maintenant que vous avez l'équilibre de l'arbre, nous pouvons compléter la structure en attribuant à chaque élément dans l'arbre, la position dans la séquence triée que cet élément appartient. Une façon de le faire est avec un ordre statistique de l'arbre, et l'autre pour effectuer une itération sur l'arbre avec un afinde de la traversée, l'annotation de chaque valeur dans l'arbre, avec sa position.
À l'aide de cette structure, nous pouvons vérifier en O(log n) si un élément est dans la bonne position par la recherche de l'élément dans l'arbre (en temps O(log n)), puis, regardant la position dans la séquence triée à laquelle elle devrait être et à la position à laquelle il est actuellement (rappelez-vous que nous avons mis cela en place lors de la création de l'arbre). Si elle n'est pas d'accord avec notre position attendue, alors qu'il est au mauvais endroit, et sinon, il est à la bonne place. Aussi, nous pouvons efficacement simuler un échange de deux éléments en regardant ces deux éléments dans l'arbre (O(log n) temps total) et puis échange de leurs positions en O(1).
Comme un résultat, nous pouvons appliquer l'algorithme ci-dessus en temps O(n log n) O(n log n) le temps de construire l'arbre, puis n itérations de faire de O(log n) travail pour déterminer si ou de ne pas remplacer.
Espérons que cette aide!
Le nombre d'échangeurs de suite les éléments nécessaires pour organiser dans leur ordre naturel est égal au nombre d'inversions dans la permutation.
Donc la solution à ce problème est de trouver le nombre d'inversions dans le tableau de nombres.
Cela peut être résolu en temps O(n log n) en utilisant la fusion de tri.
Dans l'étape de fusion et publipostage, si vous copiez un élément à partir de la droite de tableau, incrémenter un compteur global (qui compte des inversions) par le nombre d'éléments restant à gauche dans le tableau. Ceci est fait parce que l'élément à partir de la droite de tableau qui vient d'être copié est impliqué dans l'inversion de tous les éléments présents dans la gauche de la matrice.
Espère que cette aide
Je ne suis pas sûr, mais je le soupçonne de trouver le nombre minimum est un problème difficile. Sauf si il y a un raccourci, vous aurez juste être à la recherche pour optimiser tri des réseauxvous devriez être en mesure de trouver de bonnes ressources sur votre moteur de recherche préféré (ou Wikipedia).
Si vous ne se soucient que le big-O de la complexité, la réponse est
O(n log n)
et vous pouvez probablement obtenir plus concret limites (certaines constantes) si vous regardez l'analyse de certains efficace en place des algorithmes de tri comme heapsort ou smoothsort.Chaque swap dans le tri d'insertion se déplace de deux éléments adjacents - un par un, un par un et de `corrige' un seul passage en le faisant. Donc:
Annoter chaque élément, X, avec son premier index de tableau Xi.
Trier les éléments à l'aide d'un tri stable (vous pouvez utiliser quicksort, si vous traiter de la "position initiale" de l'annotation comme un mineur)
Retour moitié de la somme des différences absolues entre chaque élément annoté de la position initiale et la position finale (c'est à dire juste en boucle à travers les annotations de sommation abs(Xi - i)).
Comme la plupart des autres réponses, c'est O(n) et O(n*log n) fois. Si une fusion pourrait être modifiée à compter les passages à niveau, ce serait mieux. Je ne suis pas sûr que ça peut bien.