Quicksort avec Python
Je suis totalement nouveau pour python et je suis en train de mettre en œuvre quicksort en elle.
Quelqu'un pourrait-il svp m'aider à remplir mon code?
Je ne sais pas comment concaténer les trois tableaux et les imprimer.
def sort(array=[12,4,5,6,7,3,1,15]):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0]
for x in array:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
sort(less)
sort(pivot)
sort(greater)
Vous devez vous connecter pour publier un commentaire.
if
s dans la boucle for avecelif
etelse
pour éviter de faire des comparaisons inutilesif...elif...else
bloc, bien que je me sens bizarre édition après tant de temps, après tant de voix.sort(array)
. Alors quel est le sens de la mise en œuvre de quicksort?? Bien que beaucoup de gens l'ont aimé, mais je ne pense pas que ce sera de l'aide. Je l'ai aimé stackoverflow.com/a/27461889/1105805sorted
passort
pivot = random.choice(array)
, ce que @Brionius a des garanties écrites n(n-1)/2 = O(n2)sort()
fonction est appelée? Pythonsort()
utilise Timsort. en.wikipedia.org/wiki/Timsort je suis à la recherche pour plus de la classique version indexée pour l'éducation de l'amour.Tri rapide sans mémoire supplémentaire (en place)
Utilisation:
if end is None:
va être vérifié un grand nombre de fois, et une seule fois est-ce que ça va êtreTrue
. Vous devriez mettre cela dans une fonction wrapper de sorte qu'il n'est appelée qu'une seule fois.array[pivot], array[begin] = array[begin], array[pivot]
devrait remplacerbegin
avecend
.Il y a un autre concis et très belle version
Laissez-moi vous expliquer les codes ci-dessus pour plus de détails
choisir le premier élément du tableau
arr[0]
comme pivot[arr[0]]
qsort
ces éléments du tableau qui sont à moins de pivot avecCompréhension de Liste
qsort([x for x in arr[1:] if x < arr[0]])
qsort
ces éléments du tableau qui sont plus grands que le pivot avecList Comprehension
qsort([x for x in arr[1:] if x >= arr[0]])
sorted
, c'est clairement pour des fins éducatives. Et c'est lisible, plus lisible que la accepté de répondre.Si je recherche "python implémentation rapide" dans Google, cette question est le premier résultat de la pop. Je comprends que la question initiale était "d'aider à corriger le code" mais il y a déjà beaucoup de réponses qui font fi de la demande: actuellement deuxième plus voté un, la terrible one-liner avec l'hilarant "Vous êtes viré" commentaire et, en général, de nombreuses implémentations qui ne sont pas en place (c'est à dire l'utilisation de la mémoire supplémentaire proportionnel à l'entrée de la taille de la liste). Cette réponse fournit une solution mais c'est pour
python 2.x
. Alors, ci-dessous suit mon interprétation de la solution de Rosetta Code qui fonctionnent très bien pourpython 3
trop:Et si vous êtes prêt à renoncer à la propriété, ci-dessous est encore une autre version qui illustre le mieux les idées de base derrière quicksort. En dehors de lisibilité, son autre avantage est qu'il est stable (égal éléments apparaissent dans la liste triée dans le même ordre qu'ils ont dans la liste non triée). Cette stabilité de la propriété ne tient pas avec le moins de mémoire-faim en place la mise en œuvre décrite ci-dessus.
qsort
retour à la liste des numéros et non pas une liste arbitraire de imbriquée des sous-listes, essayez d'aplatir à l'aide de cette méthode: stackoverflow.com/a/53778278/635160Il y a plusieurs réponses à cela déjà, mais je pense que cette approche est la plus propre de la mise en œuvre:
Vous pouvez sauter de stocker le tout dans des variables et de les retourner tout de suite comme ceci:
O(N!)
? En supposant que la liste imbriquée[lesser]
et[greater]
sont les fautes de frappe, ne serait-il pas moyenO(3N logN)
qui permettrait de réduire la durée moyenneO(N logN)
? Accordé, le 3 liste des compositions de faire des travaux inutiles..Dans la vraie vie, il faut toujours utiliser la builtin sorte fournis par Python. Cependant, la compréhension de la quicksort algorithme est instructif.
Mon but ici est de décomposer le sujet tel qu'il est facilement compréhensible et reproductible par le lecteur sans avoir à revenir à des matériaux de référence.
L'algorithme quicksort est essentiellement le suivant:
Si les données sont distribuées de façon aléatoire, en sélectionnant le premier point de données comme le pivot est équivalent à une sélection aléatoire.
Lisible exemple:
Tout d'abord, regardons lisible exemple qui utilise les commentaires et les noms de variables à point pour des valeurs intermédiaires:
À reformuler l'algorithme et le code démontré ici - on déplacer les valeurs au-dessus du pivot vers la droite, et les valeurs en dessous du pivot vers la gauche, puis de transmettre ces partitions à la même fonction pour être triés.
Ont joué au golf:
Cela peut être ont joué au golf à 88 caractères:
Pour voir comment nous y rendre, prendre d'abord notre lisible par exemple, supprimer des commentaires et des docstrings, et de trouver le pivot sur place:
Maintenant trouver ci-dessous et au-dessus, au-lieu:
Maintenant, sachant que
and
renvoie l'avant de l'élément si la valeur est false, sinon si c'est vrai, il évalue et retourne l'élément suivant, nous avons:Depuis lambdas retourner une seule epression, et nous avons simplifié à une seule expression (même si elle est de plus en plus illisible) nous pouvons maintenant utiliser une lambda:
Et à réduire notre exemple, raccourcir la fonction et les noms de variable à une lettre, et d'éliminer les espaces qui ne sont pas nécessaires.
Noter que cette lambda, comme la plupart des code de golf, est plutôt mauvais style.
En place Quicksort, à l'aide de la Hoare schéma de Partitionnement
L'état de la mise en œuvre crée un grand nombre de supplémentaires inutiles listes. Si nous pouvons faire cela en place, nous allons éviter de perdre de l'espace.
Ci-dessous la mise en œuvre utilise le Hoare schéma de partitionnement, que vous pouvez en savoir plus sur wikipédia (mais nous avons apparemment enlevé jusqu'à 4 redondant de calculs par
partition()
appel à l'aide, tandis que la boucle de la sémantique au lieu de faire-tout et en déplaçant le rétrécissement étapes à la fin de la face externe de la boucle while.).Ne sais pas si je l'ai testé en profondeur:
Conclusion
Cet algorithme est souvent enseigné dans les cours d'informatique et demandé sur des entrevues d'emploi. Il nous aide à réfléchir sur la récursivité et de diviser et conquérir.
Quicksort n'est pas très pratique en Python depuis notre builtin timsort algorithme est très efficace, et nous avons la récursivité des limites. Nous nous attendons à trier la liste en place avec
liste.trier
ou en créer de nouvelles listes triées avectriés
- qui ont tous deux prendre unekey
etreverse
argument.partition
fonction ne semble pas fonctionner correctement pour:partition([5,4,3,2,1], 0, 4)
. Rendement prévu de l'indice est de 4, alors qu'il renvoie 3.approche fonctionnelle:
de programmation fonctionnelle, l'approche
Je pense que les deux réponses ici fonctionne ok pour la liste fournie (la réponse à la question d'origine), mais des pauses si un tableau contenant des valeurs uniques est passé. Donc, pour être complet, je voudrais juste souligner la petite erreur dans chaque et expliquer comment les corriger.
Par exemple en essayant de trier le tableau suivant [12,4,5,6,7,3,1,15,1] (à Noter que 1 apparaît deux fois) avec Brionius algorithme .. à un certain point va se retrouver avec la moins tableau vide et le l'égalité des tableau avec une paire de valeurs (1,1) qui ne peuvent pas être séparés dans la prochaine itération et la len() > 1...par conséquent, vous vous retrouverez avec une boucle infinie
Vous pouvez résoudre le problème en revenant tableau si moins est vide ou mieux par pas l'appel de tri dans votre égal tableau, comme dans zangw réponse
L'amateur solution aussi des pauses, mais pour un motif différent, il est absent de la retour clause de la récursivité de la ligne, qui fera à un certain moment de retourner Aucun et essayez de les ajouter à une liste ....
Pour corriger, il suffit d'ajouter un retour à la ligne
Partition - division d'un tableau par un pivot que les plus petits éléments se déplacer vers la gauche et une plus grande elemets déplacer vers la droite ou vice versa. Un pivot peut être un élément aléatoire à partir d'un tableau. Pour faire de cet algorithme, nous avons besoin de savoir ce qui est de début et de fin de l'index d'un tableau et où est un point de pivot. Placez ensuite deux auxiliaires pointeurs L, R.
Nous avons donc un tableau de l'utilisateur[...,commencer,...,fin,...]
La position de départ de L et les R de pointeurs
[...,commencer,ensuite,...,fin,...]
N L
alors que L < fin
1. Si un utilisateur[pivot] > utilisateur[L], puis déplacez R par un et swap de l'utilisateur[R] avec l'utilisateur[L]
2. déplacer L par un
Après tout swap de l'utilisateur[R] avec l'utilisateur[pivot]
tri Rapide - Utiliser la partition de l'algorithme jusqu'à ce que chaque partie suivante de la division par un pivot devra commencer indice supérieur ou égal que la fin de l'index.
Ceci est une version de la quicksort à l'aide de Hoare schéma de partition et avec moins de swaps et des variables locales
Je sais que beaucoup de personnes ont répondu à cette question correctement et j'ai apprécié la lecture. Ma réponse est presque le même que zangw mais je pense que la précédente, les contributeurs n'ont pas fait un bon travail d'expliquer visuellement comment les choses fonctionnent...donc voici ma tentative pour aider les autres qui viennent à cette question/réponses dans le futur sur une solution simple pour une implémentation rapide.
Comment ça fonctionne ?
Voici un exemple avec visual pour aller avec elle ...
(pivot)9,11,2,0
moyenne: n log n
pire des cas: n^2
Le code:
items=[9,11,2,0]
print(quicksort(articles))
Ou si vous préférez un one-liner qui illustre aussi le Python équivalent de C/C++ varags, les expressions lambda, et si les expressions:
Un "vrai" sur place la mise en œuvre [des Algorithmes de 8,9, 8.11 de la Conception d'algorithmes et Applications Livre de Michael T. Goodrich et Roberto Tamassia]:
L'algorithme a 4 étapes simples:
Code pour l'algorithme en python:
Continuer avec cet algorithme récursivement avec les parties gauche et droite.
Une autre implémentation rapide:
Pour La Version Python 3.x: une fonctionnelle de style à l'aide de
operator
module, principalement pour améliorer la lisibilité.et est testé comme
… complete my code?
. À l'aide delambda
de définirsublist()
ne regarde pas strictement nécessaire.sublist
être définies que parfilter
? Est-il même possible?def
- n'a pas commencé à bricoler mais comme je suis à essayer de comprendre si il ya un moyen plus efficace de "distribuer" les éléments d'un objet iterable à des listes distinctes (ou, à défaut, une seule liste, avec une "catégorie" d'après les autres).)Voici une mise en œuvre simple:-
L'algorithme contient deux limites, l'une ayant des éléments de moins que le pivot (suivis par l'indice "j") et l'autre ayant des éléments plus grand que le pivot (suivis par l'indice "i").
À chaque itération, un nouvel élément est traité par incrémentation j.
Invariant:-
Si l'invariant est violé, ith et jth éléments sont inversés, et je
est incrémenté.
Après tous les éléments ont été traitées, et tout ce qui est après le pivot
a été partitionné, le pivot de l'élément est échangé avec le dernier élément
plus petit que lui.
Le pivot de l'élément va maintenant être à sa place dans la séquence. L'
les éléments avant de il sera de moins que lui et les uns après il sera
plus grand qu'elle, et ils seront triés.
De la sélection d'un pivot
Un "bon" pivot sera résultat en deux sous-séquences d'à peu près la même
taille. De façon déterministe, un pivot de l'élément peut être sélectionné dans une
naïf manière ou par le calcul de la médiane de la séquence.
Une implémentation naïve de la sélection d'un pivot sera le premier ou le dernier
de l'élément. Le pire cas d'exécution dans ce cas lorsque l'entrée
la séquence est déjà trié ou l'inverse triés, comme l'un des sous-séquences
sera vide qui va causer un seul élément à être enlevé par
appel récursif.
Parfaitement équilibré split est atteint lorsque le pivot est la médiane
élément de la séquence. Il y a un nombre égal d'éléments plus
que et moins que cela. Cette approche garantit une amélioration d'ensemble de l'
temps d'exécution, mais est beaucoup plus de temps.
Un non-déterministe ou aléatoire façon de sélectionner le pivot serait de choisir
un élément uniformément au hasard. C'est un simple et léger
approche qui permettra de réduire au minimum le scénario du pire et aussi conduire à une
à peu près équilibrées split. Cela permettra également de fournir un équilibre entre l'approche naïve et la médiane à l'approche de la sélection du pivot.
pivot_value et nous avons également établi la gauche et droit des marques
la partition de processus à exécuter à nouveau si il n'est pas satisfait de la
condition nécessaire
satisfait de la bonne condition. Si c'est le cas, nous le marquer comme terminée,
si pas de nous changer de la gauche et la droite des valeurs et de l'appliquer de nouveau
split_point
Je joins le code ci-dessous! Ce tri rapide est un excellent outil d'apprentissage en raison de la Emplacement du pivot de la valeur. Depuis qu'il est dans une place constante, vous pouvez marcher à travers elle plusieurs fois et vraiment obtenir un blocage de la façon dont tout cela fonctionne. Dans la pratique, il est préférable de rendre aléatoire le pivot pour éviter de O(N^2) l'exécution.
Exemple complet avec imprimé des variables lors de la partition de l'étape:
Cet algorithme n'utilise pas de fonctions récursives.
Laisser
N
être une liste de nombres aveclen(N) > 0
. EnsembleK = [N]
et exécuter le programme suivant.Note: Ceci est un stable algorithme de tri.
Facilité de mise en œuvre de grokking algorithmes
inlace sorte
sans récursivité:
Au lieu de prendre trois différents tableaux pour moins égale plus et alors la concaténation de tous les essayer le concept traditionnel(méthode de partitionnement):
http://pythonplanet.blogspot.in/2015/08/quick-sort-using-traditional-partition.html
c'est sans l'aide de tous intégré la fonction.
fonction de partitionnement -
alist[i], alist[j] = alist[j], alist[i]
Je vais faire quicksort utilisation de numpy bibliothèque. Je pense qu'il est vraiment utile de la bibliothèque. Ils ont déjà mis en place le tri rapide méthode, mais vous pouvez implment aussi votre méthode personnalisée.