Explication de la Fusion de Tri pour les Nuls
J'ai trouvé cette ligne de code:
def merge(left, right):
result = []
i ,j = 0, 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
def mergesort(list):
if len(list) < 2:
return list
middle = len(list) / 2
left = mergesort(list[:middle])
right = mergesort(list[middle:])
return merge(left, right)
Il fonctionne à 100%, quand je le lance. Je n'ai juste pas vraiment comment la fusion de tri ou comment fonctionne la fonction récursive est en mesure de commander à la fois à gauche et une à droite.
- Vérifiez que le gif animé sur la page du wiki: en.wikipedia.org/wiki/Merge_sort
Vous devez vous connecter pour publier un commentaire.
Je crois que la clé de la compréhension de fusion de tri est de comprendre le principe suivant -- je vais l'appeler le principe de fusion:
Si vous travaillez en main quelques fois, vous verrez que c'est correct. Par exemple:
Maintenant Un est épuisé, afin d'étendre C avec les valeurs restantes de B:
La fusion principe est également facile à prouver. La valeur minimale de A est inférieur à toutes les autres valeurs de A, et la valeur minimale de B est inférieure à toutes les autres valeurs de B. Si la valeur minimale de A est inférieure à la valeur minimale de B, alors il doit aussi être moins cher que toutes les valeurs de B. par conséquent, il est moins cher que toutes les valeurs de A et de toutes les valeurs de B.
Donc, tant que vous gardez en ajoutant la valeur qui correspond à ces critères de C, vous obtenez une liste triée. C'est ce que le
merge
la fonction ci-dessus ne.Maintenant, compte tenu de ce principe, il est très facile de comprendre une technique de tri qui trie une liste en le divisant en petites listes, le tri de ces listes, puis la fusion des listes triées ensemble. Le
merge_sort
fonction est simplement une fonction qui divise une liste de moitié, sortes de ces deux listes, puis fusionne les deux listes d'ensemble de la manière décrite ci-dessus.Le seul hic est que parce qu'il est récursif, quand il trie les deux sous-listes, il le fait en les transmettant à lui-même! Si vous éprouvez de la difficulté à comprendre la récursivité ici, je vous suggère d'étudier plus simple problème en premier. Mais si vous obtenez les bases de la récursivité déjà, alors tout ce que vous avez à réaliser est qu'un élément de la liste est déjà triée. La fusion de deux listes d'objets génère un triées deux-élément de la liste; la fusion de deux listes d'objets génère une triés quatre-élément de la liste, et ainsi de suite.
A
etB
sont les intrants dans l'opération de fusion, etC
est la sortie. Est-il quelque chose de spécifique qui n'est pas clair?Quand je suis tombé dans la difficulté à uderstand fonctionnement de l'algorithme, - je ajouter de la sortie de débogage pour vérifier ce qui se passe réellement à l'intérieur de l'algorithme.
Voici le code avec la sortie de débogage. Essayez de uderstand toutes les étapes avec les appels récursifs de
mergesort
et cemerge
ne avec le de sortie:De sortie:
De fusion tri a toujours été un de mes préférés des algorithmes.
Vous commencez par de courtes séquences triées et garder leur fusion, dans l'ordre, dans les plus grandes séquences triées. Si simple.
La partie récursive signifie que vous travaillez à rebours, en commençant par l'ensemble de la séquence de tri et les deux moitiés. Chaque semestre est également divisé, jusqu'à ce que le tri devient facile quand il n'y a qu'zéro ou un élément dans la séquence. Comme le recursed retour des fonctions de l'séquences triées sont de plus en plus comme je l'ai dit dans la description initiale.
Un couple de façons de vous aider à comprendre ceci:
Parcourir le code dans un débogueur et regarder ce qui se passe.
Ou,
Étape à travers elle sur le papier (avec un tout petit exemple) et de regarder ce qui se passe.
(personnellement, je trouve ce genre de chose sur le papier plus instructif)
Conceptuel, il fonctionne comme ceci:
La liste d'entrée reçois haché en petits morceaux par être réduit de moitié (par exemple
list[:middle]
est de la première moitié). Chaque semestre est divisé par deux, encore et encore, jusqu'à ce qu'il a une longueur de moins de 2. I. e. jusqu'à ce qu'il n'est rien du tout, ou un seul élément. Ces morceaux sont ensuite combinés par la fusion de routine, en ajoutant ou en entrelaçant les 2 sous-listes pour leresult
liste, et par conséquent, vous obtenez une liste triée. Parce que les 2 sous-listes doivent être triées, l'ajout/interleave est rapide (O(n)) de l'opération.La clé de la ce (à mon avis) n'est pas la fusion de la routine, c'est assez évident, une fois que vous comprenez que les entrées, il sera toujours triés. Le "truc" (j'utilise des guillemets parce que ce n'est pas une astuce, c'est de l'informatique: -) ), c'est que, afin de garantir que les données à fusionner sont triés, vous devez garder recursing vers le bas jusqu'à ce que vous arriver à une liste qui doit être triés, et c'est pourquoi vous gardez de manière récursive appel
mergesort
jusqu'à ce que la liste est à moins de 2 éléments de long.La récursivité, et, par extension, de fusion et de tri, peut être non évidente lors de la première à venir à travers eux. Vous pourriez consulter un bon algorithmes livre (par exemple, DPV est disponible en ligne, gratuitement et en toute légalité), mais vous pouvez aller un long chemin en parcourant le code que vous avez. Si vous vraiment voulez obtenir dans la Stanford/Coursera algo cours seront en cours d'exécution à nouveau bientôt et il se couvre de Fusion de tri dans les moindres détails.
Si vous vraiment veulent comprendre, lire le chapitre 2 de ce livre de référence, puis jeter le code ci-dessus et ré-écrire à partir de zéro. Sérieusement.
Une image vaut mille mots, et une animation montant de 10 000.
La caisse de l'animation suivante prises de Wikipédia qui va vous aider à visualiser comment la fusion algorithme de tri fonctionne réellement.
Détaillée animation avec explication pour chaque étape dans le processus de tri pour les curieux chers.
Un autre intéressant d'animation de différents types d'algorithmes de tri.
fondamentalement, vous obtenez votre liste, vous diviser, puis à les trier, mais vous appliquez cette méthode récursive si vous vous retrouvez crève à nouveau, et encore jusqu'à ce que vous avez un trivial que vous pouvez trier facilement et puis fusionner tous les simples solutions à un tableau trié.
Vous pouvez avoir une bonne visualisation sur la façon dont la fusion tri fonctionne ici:
http://www.ee.ryerson.ca/~courses/coe428/sorting/mergesort.html
J'espère que cela aide.
Comme le Wikipédia article explique, il y a de nombreuses façons d'accomplir une sorte de fusion. La manière d'accomplir une opération de fusion dépend aussi de la collection de choses pour être fusionnées, certaines collections de permettre à certains des outils que la collection a à sa disposition.
Je ne vais pas répondre à cette question à l'aide de Python, tout simplement parce que je ne peux pas l'écrire; toutefois, en prenant une partie de la "fusion de tri" algorithme semble vraiment être au cœur de la question, au sens large. Une ressource qui m'a aidé est le K. I. T. E est assez obsolète page web sur l'algorithme (écrit par un professeur), tout simplement parce que l'auteur du contenu élimine contexte des identificateurs significatifs.
Ma réponse est dérivée à partir de cette ressource.
Rappelez-vous, fusionner les algorithmes de tri de travail en démontant le fourni de collecte et de placer chacun des éléments individuels de nouveau ensemble, en comparant les pièces les unes aux autres, comme la collection est re-construit.
Ici, est le "code" (regardez à la fin pour un Java "violon"):
J'ai aussi une version, ici, qui permet d'imprimer des informations utiles et fournir une représentation visuelle de ce qui se passe au-dessus. La coloration syntaxique est mieux aussi, si c'est utile.