Реализация алгоритмов сортировки (слияния и быстрой сортировки) с Tkinter - PullRequest
0 голосов
/ 27 октября 2019

Я изучаю биоинформатику и работаю над групповым проектом. Эта работа включает в себя реализацию некоторых расширенных алгоритмов сортировки и их визуализацию с помощью 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()
...