Я изучаю биоинформатику и работаю над групповым проектом. Эта работа включает в себя реализацию некоторых расширенных алгоритмов сортировки и их визуализацию с помощью tkinter. Но у меня проблема с реализацией слияния и быстрой сортировки. Метод «generer» генерирует список столбцов длины от 1 до 600. Метод echange_position меняет позиции между двумя столбцами. Проблема заключается в том, что с сортировкой быстрого типа и слиянием я не могу вызвать метод echange_position, поскольку принцип этих двух сортировок не включает обмен между двумя значениями. Поэтому я должен переопределить специальный метод только для этих двух видов. Помощь будет приветствоваться и извините за мой плохой английский.
import tkinter as tk
import random
# TRI PAR INSERTION
def _insertion_tri():
global barre_liste
global longueur_liste
for i in range(len(longueur_liste)):
curseur = longueur_liste[i]
curseur_Barre = barre_liste[i]
pos = i
while pos > 0 and longueur_liste[pos - 1] > curseur:
longueur_liste[pos] = longueur_liste[pos - 1]
barre_liste[pos], barre_liste[pos - 1] = barre_liste[pos - 1], barre_liste[pos]
echange_position(barre_liste[pos], barre_liste[pos - 1]) # Met à jour l'affichage
yield # Suspend l'exécution
pos -= 1 # L'exécution se résume ici lorsque les prochaines instructions
# sont appelées
longueur_liste[pos] = curseur
barre_liste[pos] = curseur_Barre
echange_position(barre_liste[pos], curseur_Barre)
utilisateur = None
def insertion_tri():
global utilisateur
utilisateur = _insertion_tri()
animate()
# TRI A BULLE
def _tri_bulle():
permutation = True
passage = 0
while permutation == True:
permutation = False
passage = passage + 1
for pos in range(0, len(longueur_liste) - passage):
if longueur_liste[pos] > longueur_liste[pos + 1]:
permutation = True
# On echange les deux elements
longueur_liste[pos], longueur_liste[pos + 1] = longueur_liste[pos + 1], longueur_liste[pos]
barre_liste[pos], barre_liste[pos + 1] = barre_liste[pos + 1], barre_liste[pos]
echange_position(barre_liste[pos], barre_liste[pos + 1]) # Met à jour l'affichage
yield
utilisateur = None
def tri_bulle(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = _tri_bulle()
animate()
# TRI PAR SELECTION
def _tri_selection():
nb = len(longueur_liste)
for en_cours in range(0,nb):
plus_petit = en_cours
for j in range(en_cours+1,nb):
if longueur_liste[j] < longueur_liste[plus_petit]:
plus_petit = j
if min is not en_cours :
temp = longueur_liste[en_cours]
longueur_liste[en_cours] = longueur_liste[plus_petit]
longueur_liste[plus_petit] = temp
barre_liste[en_cours], barre_liste[plus_petit] = barre_liste[plus_petit], barre_liste[en_cours]
echange_position(barre_liste[en_cours], barre_liste[plus_petit]) # Met à jour l'affichage
yield
utilisateur = None
def tri_selection(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = _tri_selection()
animate()
# TRI PAR TAS
def heapify(n, i):
largest = i
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
if l < n and longueur_liste[i] < longueur_liste[l]:
largest = l
if r < n and longueur_liste[largest] < longueur_liste[r]:
largest = r
if largest != i:
longueur_liste[i], longueur_liste[largest] = longueur_liste[largest], longueur_liste[i] # swap
barre_liste[i], barre_liste[largest] = barre_liste[largest], barre_liste[i]
echange_position(barre_liste[i], barre_liste[largest])
heapify(n, largest)
def heapSort():
n = len(longueur_liste)
for i in range(n, -1, -1):
heapify(n, i)
for i in range(n - 1, 0, -1):
longueur_liste[i], longueur_liste[0] = longueur_liste[0], longueur_liste[i]
barre_liste[i], barre_liste[0] = barre_liste[0], barre_liste[i]
echange_position(barre_liste[0], barre_liste[i])
yield
heapify(i, 0)
utilisateur = None
def _heapSort(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = heapSort()
animate()
# TRI A PEIGNE
import math
def tri_peigne():
permutation = True
gap = len(longueur_liste)
while (permutation == True) or (gap>1):
permutation = False
gap = math.floor(gap / 1.3)
if gap<1: gap = 1
for en_cours in range(0, len(longueur_liste) - gap):
if longueur_liste[en_cours] > longueur_liste[en_cours + gap]:
permutation = True
# On echange les deux elements
longueur_liste[en_cours], longueur_liste[en_cours + gap] = longueur_liste[en_cours + gap],longueur_liste[en_cours]
barre_liste[en_cours], barre_liste[en_cours + gap] = barre_liste[en_cours + gap], barre_liste[en_cours]
echange_position(barre_liste[en_cours], barre_liste[en_cours + gap])
yield
def _tri_peigne(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = tri_peigne()
animate()
# TRI SHAKER (COCKTAIL)
def tri_shaker():
permutation,sens,en_cours = True,1,0
debut,fin = 0,len(longueur_liste)-2
while permutation == True:
permutation = False
while (en_cours<fin and sens==1) or \
(en_cours>debut and sens==-1) :
# Test si echange
if longueur_liste[en_cours] > longueur_liste[en_cours + 1]:
permutation = True
# On echange les deux elements
longueur_liste[en_cours], longueur_liste[en_cours + 1] = longueur_liste[en_cours + 1],longueur_liste[en_cours]
barre_liste[en_cours], barre_liste[en_cours + 1] = barre_liste[en_cours + 1], barre_liste[en_cours]
echange_position(barre_liste[en_cours], barre_liste[en_cours + 1])
yield
en_cours = en_cours + sens
# On change le sens du parcours
if sens==1:
fin = fin - 1
else:
debut = debut + 1
sens = -sens
def _tri_shaker(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = tri_shaker()
animate()
# TRI GNOME
def tri_gnome():
i_b,i_i,taille = 1,2,len(longueur_liste)
while i_b < taille:
if longueur_liste[i_b-1] <= longueur_liste[i_b]:
i_b,i_i = i_i, i_i+1
else:
longueur_liste[i_b-1],longueur_liste[i_b] = longueur_liste[i_b],longueur_liste[i_b-1]
barre_liste[i_b-1], barre_liste[i_b] = barre_liste[i_b], barre_liste[i_b-1]
echange_position(barre_liste[i_b], barre_liste[i_b-1])
yield
i_b -= 1
if i_b == 0:
i_b,i_i = i_i, i_i+1
def _gnome(): # Commande le démarrage du tri et de l'animation
global utilisateur
utilisateur = tri_gnome()
animate()
# ECHANGE POSITION
def echange_position(pos_0, pos_1):
Bar_1_1, _, Bar_1_2, _ = canvas.coords(pos_0)
Bar_2_1, _, Bar_2_2, _ = canvas.coords(pos_1)
canvas.move(pos_0, Bar_2_1 - Bar_1_1, 0)
canvas.move(pos_1, Bar_1_2 - Bar_2_2, 0)
# ANIMATION
def animate():
global utilisateur
if utilisateur is not None:
try:
next(utilisateur)
window.after(10, animate) # Répeter jusqu'à ce que le tri soit complet
except StopIteration: # lorsque le générateur est épuisé
utilisateur = None
finally:
window.after_cancel(animate) # Stop les rappels
# GENERATION DE VALEURS ALEATOIRES ENTRE 1 ET 390
def generer():
global barre_liste
global longueur_liste
canvas.delete('all')
x_start = 5
x_end = 15
barre_liste = []
longueur_liste = []
for x in range(1, 80):
random_Y = random.randint(1, 600)
x = canvas.create_rectangle(x_start, random_Y, x_end, 650, fill='red')
barre_liste.append(x)
x_start += 10
x_end += 10
for barre in barre_liste:
x = canvas.coords(barre)
length = x[3] - x[1]
longueur_liste.append(length)
for i in range(len(longueur_liste) - 1):
if longueur_liste[i] == min(longueur_liste):
canvas.itemconfig(barre_liste[i], fill='blue')
elif longueur_liste[i] == max(longueur_liste):
canvas.itemconfig(barre_liste[i], fill='yellow')
window = tk.Tk()
window.title('Algorithmes de tri')
window.geometry('820x640')
canvas = tk.Canvas(window, width='820', height='600')
canvas.grid(column=0,row=0, columnspan = 50)
insert = tk.Button(window, text='Insertion', command=insertion_tri)
gen = tk.Button(window, text='Générer', command=generer)
bulle = tk.Button(window, text='Bulle', command=tri_bulle)
select = tk.Button(window, text='Selection', command=tri_selection)
heap = tk.Button(window, text='Heap', command=_heapSort)
peigne = tk.Button(window, text='Peigne', command=_tri_peigne)
shaker = tk.Button(window, text='Shaker', command=_tri_shaker)
gnome = tk.Button(window, text='Gnome', command=_gnome)
insert.grid(column=1,row=1)
gen.grid(column=0, row=1)
bulle.grid(column=2, row=1)
select.grid(column=3, row=1)
heap.grid(column=4, row=1)
peigne.grid(column=5, row=1)
shaker.grid(column=6, row=1)
gnome.grid(column=7, row=1)
generer()
window.mainloop()