Visualisieren Sie, wie Daten mit Pythons Tkinter sortiert werden
"Das war's!"
Es ist ein Code, der zu sein scheint.
before
 after
after

Wie der Inhalt
--Schnelle Sorte --Zusammenführen, sortieren
Wird hinausgetragen werden. Hier ist der Beispielcode. Erstellen Sie einige Klassen. Dann erstellen Sie eine Funktion.
sortSample.py
# =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
#Mit tkinter und Zeitschaltuhren
#Visualisieren Sie die Sortierung
#    2020.06.19 ProOJI
# =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
import tkinter
import time
#Leinwandgröße
CANVAS_WIDTH = 600
CANVAS_HEIGHT = 400
#Gewicht zum Zeitpunkt der Zeichnung (en)
WAIT = 0
class Sort():
    #Sortiertyp
    SELECTION_SORT = 1
    QUICK_SORT = 2
    MERGE_SORT = 3
    def __init__(self, view):
        'Objekterstellung zum Sortieren'
        self.view = view
    def start(self, data, method):
        'Starten Sie die Sortierung'
        #Legen Sie eine Liste der zu sortierenden Daten fest
        self.data = data
        #Legen Sie die Anzahl der zu sortierenden Daten fest
        self.num = len(data)
        #Initialisierung der Vergleichszahl
        self.compare_num = 0
        #Führen Sie die Sortierung nach Methode durch
        if method == Sort.SELECTION_SORT:
            #Wählen Sie die Sortierausführung
            self.selection_sort(0, self.num - 1)
        elif method == Sort.QUICK_SORT:
            #Schnelle Sortierung ausführen
            self.quick_sort(0, self.num - 1)
        elif method == Sort.MERGE_SORT:
            #Bereiten Sie den Arbeitsspeicher für die Zusammenführungssortierung vor
            self.work = [0] * self.num
            #Sortierausführung zusammenführen
            self.merge_sort(0, self.num - 1)
        for num in self.data:
            print(num)
        #Geben Sie die Anzahl der Vergleiche zurück
        return self.compare_num
    def selection_sort(self, left, right):
        'Führen Sie eine Auswahlsortierung durch'
        if left == right:
            #Da es nur einen Datenbestand gibt, endet die Sortierung
            return
        #Bestimmen Sie vorübergehend den Mindestwert
        min = self.data[left]
        i_min = left
        #Suchen Sie nach dem Mindestwert aus dem Sortierbereich
        for i in range(left, right + 1):
            if min > self.data[i]:
                #Aktualisierung des Mindestwerts
                min = self.data[i]
                i_min = i
            #Erhöhen Sie die Anzahl der Vergleiche
            self.compare_num += 1
        #Tauschen Sie den Mindestwert und die Daten ganz links aus
        if i_min != left:
            #Nur bei Bedarf ersetzen
            tmp = self.data[left]
            self.data[left] = self.data[i_min]
            self.data[i_min] = tmp
        #Aktuelle Datenfolge anzeigen
        self.view.draw_data(self.data)
        #Grenzen Sie den Bereich ein und wählen Sie ihn erneut aus
        self.selection_sort(left + 1, right)
    def quick_sort(self, left, right):
        'Führen Sie eine schnelle Sortierung durch'
        if left >= right:
            #Die Sortierung endet, da die Anzahl der Daten 1 oder weniger beträgt
            return
        #Pivot-Bestimmung
        pivot = self.data[left]
        i = left
        j = right
        #Platzieren Sie die Zahlen unter dem Drehpunkt in der ersten Hälfte des Arrays.
        #Sammeln Sie Zahlen über dem Pivot in der zweiten Hälfte des Arrays
        while True:
            #Suchen Sie nach Zahlen über dem Drehpunkt von links
            while self.data[i] < pivot:
                i += 1
                #Erhöhen Sie die Anzahl der Vergleiche
                self.compare_num += 1
            #Suchen Sie nach Zahlen unter dem Drehpunkt von rechts
            while self.data[j] > pivot:
                j -= 1
                #Erhöhen Sie die Anzahl der Vergleiche
                self.compare_num += 1
            # i >=J werden heißt
            #Die Zahlen darunter drehen sich auf der linken Seite des Arrays
            #Dass die Zahlen über dem Pivot auf der rechten Seite des Arrays gesammelt werden
            if i >= j:
                #Der Teilungsprozess des Satzes ist abgeschlossen
                break
            #Tauschen Sie die beiden gesuchten Nummern aus
            tmp = self.data[i]
            self.data[i] = self.data[j]
            self.data[j] = tmp
            #Die Suche wird ab der nächsten Nummer nach dem Austausch fortgesetzt
            i += 1
            j -= 1
        #Aktuelle Datenfolge anzeigen
        self.view.draw_data(self.data)
        #Sortieren Sie nach einer Reihe kleiner Zahlen
        self.quick_sort(left, i - 1)
        #Sortieren Sie nach einer Reihe großer Zahlen
        self.quick_sort(j + 1, right)
    def merge_sort(self, left, right):
        'Führen Sie eine Zusammenführungssortierung durch'
        if left == right:
            #Da es nur einen Datenbestand gibt, endet die Sortierung
            return
        #Teilen Sie das Set in der Mitte in zwei Teile
        mid = (left + right) // 2
        #Sortieren Sie die Daten jedes Satzes nach der Division
        self.merge_sort(left, mid)
        self.merge_sort(mid + 1, right)
        #Führen Sie jeden sortierten Satz zusammen
        self.merge(left, mid, right)
        #Aktuelle Datenfolge anzeigen
        self.view.draw_data(self.data)
    def merge(self, left, mid, right):
        'Sätze zusammenführen'
        #Stellen Sie den Startpunkt des ersten Satzes ein
        i = left
        #Stellen Sie den Startpunkt des zweiten Satzes ein
        j = mid + 1
        #Legen Sie den Startpunkt des Zusammenführungszielsatzes fest
        k = 0
        #Einer der beiden Sätze
        #Schleife, bis alle zusammengeführt sind
        while i <= mid and j <= right:
            #Erhöhen Sie die Anzahl der Vergleiche
            self.compare_num += 1
            #Von den beiden Sätzen ohne die zusammengeführten Daten
            #Führen Sie die kleineren der ersten Daten zusammen
            if (self.data[i] < self.data[j]):
                self.work[k] = self.data[i]
                #Der Index der zusammengeführten Menge und
                #Erhöhen Sie den Index des Zusammenführungszielsatzes
                i += 1
                k += 1
            else:
                self.work[k] = self.data[j]
                #Der Index der zusammengeführten Menge und
                #Erhöhen Sie den Index des Zusammenführungszielsatzes
                j += 1
                k += 1
        #Eine Reihe von nicht zusammengeführten Daten
        #In den Zusammenführungszielsatz einbinden
        while i <= mid:
            #Erhöhen Sie die Anzahl der Vergleiche
            self.compare_num += 1
            self.work[k] = self.data[i]
            i += 1
            k += 1
        while j <= right:
            #Erhöhen Sie die Anzahl der Vergleiche
            self.compare_num += 1
            self.work[k] = self.data[j]
            j += 1
            k += 1
        #Kopieren Sie den Zusammenführungszielsatz in Daten
        j = 0
        for i in range(left, right + 1):
            self.data[i] = self.work[j]
            j += 1
class View():
    def __init__(self, master):
        'UI-bezogene Objekterzeugung'
        #verschiedene Einstellungen
        self.drawn_obj = []
        #Bestimmen Sie die Größe der Leinwand
        self.canvas_width = CANVAS_WIDTH
        self.canvas_height = CANVAS_HEIGHT
        #Erstellen Sie einen Rahmen für die Anzeige von Informationen
        self.canvas_frame = tkinter.Frame(
            master,
        )
        self.canvas_frame.grid(column=1, row=1)
        #Erstellen Sie einen Rahmen für das Operations-Widget
        self.operation_frame = tkinter.Frame(
            master,
        )
        self.operation_frame.grid(column=2, row=1, padx=10)
        #Erzeugung und Platzierung von Leinwänden
        self.canvas = tkinter.Canvas(
            self.canvas_frame,
            width=self.canvas_width,
            height=self.canvas_height,
        )
        self.canvas.pack()
        #Etikettenerstellung und -platzierung
        self.text = tkinter.StringVar()
        self.text.set("Drücken Sie die Starttaste")
        self.label = tkinter.Label(
            self.canvas_frame,
            textvariable=self.text,
        )
        self.label.pack()
        #Generieren und Anordnen von Frames für die Platzierung von Textfeldern
        max_w = CANVAS_WIDTH // 2
        max_h = CANVAS_HEIGHT // 2
        if max_w < max_h:
            max = max_w
        else:
            max = max_h
        self.text_frame = tkinter.LabelFrame(
            self.operation_frame,
            text="Anzahl der Daten (maximal" + str(max) + ")"
        )
        self.text_frame.pack(ipadx=10, pady=10)
        self.entry = tkinter.Entry(
            self.text_frame,
            width=4
        )
        self.entry.pack()
        #Generierung und Platzierung von Frames für die Platzierung von Optionsfeldern
        self.radio_frame = tkinter.LabelFrame(
            self.operation_frame,
            text="Algorithmus"
        )
        self.radio_frame.pack(ipadx=10, pady=10)
        #Objekterzeugung zum Abrufen der aktivierten Schaltfläche
        self.sort = tkinter.IntVar()
        self.sort.set(Sort.QUICK_SORT)
        #Erstellen und platzieren Sie 3 Optionsfelder für die Algorithmusauswahl
        self.selection_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Selektive Sortierung",
            value=Sort.SELECTION_SORT
        )
        self.selection_button.pack()
        self.quick_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Schnelle Sorte",
            value=Sort.QUICK_SORT
        )
        self.quick_button.pack()
        self.merge_button = tkinter.Radiobutton(
            self.radio_frame,
            variable=self.sort,
            text="Zusammenführen, sortieren",
            value=Sort.MERGE_SORT
        )
        self.merge_button.pack()
        #Generierung und Platzierung von Starttasten
        self.button = tkinter.Button(
            self.operation_frame,
            text="Start",
        )
        self.button.pack()
    def start(self, n):
        'Hintergrund zeichnen'
        #Stellen Sie die Anzahl der Daten ein
        self.num = n
        #Bestimmen Sie die Breite der Linie, die ein Datenbild darstellt
        self.line_width = CANVAS_WIDTH / self.num
        #Bestimmen Sie die Zeilenhöhe des Datenwerts 1
        #Wenn der Datenwert N ist, ist die Zeilenhöhe self.line_height *Werden Sie N.
        self.line_height = CANVAS_HEIGHT / self.num
        #Wenn zu viele Daten zum Zeichnen vorhanden sind
        if self.line_width < 2 or self.line_height < 2:
            return False
        #Zur Einstellung der Hintergrundposition (zentriert)
        self.offset_x = int(
            (self.canvas.winfo_width() - self.line_width * self.num) / 2
        )
        self.offset_y = int(
            (self.canvas.winfo_height() - self.line_height * self.num + 1) / 2
        )
        #Löschen Sie die einmal gezeichneten Daten
        for obj in self.drawn_obj:
            self.canvas.delete(obj)
        #Leeren Sie die gezeichnete Datenliste, da sie gelöscht wurde
        self.drawn_obj = []
        #Hintergrundobjekt vorab löschen
        self.canvas.delete("background")
        #Hintergrund zeichnen
        self.canvas.create_rectangle(
            self.offset_x,
            self.offset_y,
            int(self.offset_x + self.line_width * self.num),
            int(self.offset_y + self.line_height * self.num),
            width=0,
            fill="#EEEEFF",
            tag="background"
        )
        #Zeichnung sofort reflektieren
        self.canvas.update()
        return True
    def get_algorithm(self):
        'Sortieralgorithmus-Erfassung'
        return self.sort.get()
    def get_data_num(self):
        'Holen Sie sich die Anzahl der Daten'
        return int(self.entry.get())
    def draw_data(self, data):
        'Zeichnen Sie eine Datenfolge als Linie'
        #Löschen Sie die einmal gezeichneten Daten
        for obj in self.drawn_obj:
            self.canvas.delete(obj)
        #Leeren Sie die gezeichnete Datenliste, da sie gelöscht wurde
        self.drawn_obj = []
        #Zeichnen Sie die Zahlen in der Liste als Rechteck
        i = 0
        for value in data:
            #Bestimmen Sie den Start- und Endpunkt des Rechtecks
            #Bestimmen Sie die horizontalen Koordinaten des Rechtecks aus der Datenposition
            x1 = int(self.offset_x + i * self.line_width)
            x2 = int(self.offset_x + (i + 1) * self.line_width)
            #Bestimmen Sie die vertikalen Koordinaten des Rechtecks aus den Datenwerten
            y1 = int(self.offset_y + self.line_height * (self.num - value))
            y2 = int(self.offset_y + self.line_height * self.num)
            #Fügen Sie ein Tag hinzu, damit Sie es später löschen können
            tag = "line" + str(i)
            self.drawn_obj.append(tag)
            #Zeichne ein Rechteck
            self.canvas.create_rectangle(
                x1, y1,
                x2, y2,
                tag=tag,
                fill="#FFA588",
                width=1
            )
            i += 1
        #Zeichnung sofort reflektieren
        self.canvas.update()
        #Schlaf für Sekunden warten
        time.sleep(WAIT)
    def update_message(self, text):
        'Aktualisieren Sie die Nachricht, um sie auf dem Etikett anzuzeigen'
        #Legen Sie die Zeichenfolge fest, die auf dem Etikett gezeichnet werden soll
        self.text.set(text)
        #Zeichnung sofort reflektieren
        self.label.update()
class Controller():
    def __init__(self, view, sort):
        'Erstellen Sie Objekte zur Steuerung von Sortieren und Anzeigen'
        #Zu steuernde Objekteinstellungen anzeigen und sortieren
        self.view = view
        self.sort = sort
        #Akzeptiert Ereignisse, wenn auf die Schaltfläche geklickt wird
        self.view.button["command"] = self.button_click
    def button_click(self):
        'Verarbeitung beim Klicken auf eine Schaltfläche'
        num = self.view.get_data_num()
        #Ansicht starten
        if not self.view.start(num):
            #Nachrichtenaktualisierung
            self.view.update_message(
                "Zu viele Daten"
            )
            #Tu nichts, wenn du versagst
            return
        #Generieren Sie eine zufällige Liste der Anzahl der Daten NUM mit NUM als Maximalwert
        data = []
        for _ in range(num):
            import random
            data.append(int(random.randint(0, num - 1)))
        #Bei Bestellung der Ausgangsdaten in absteigender Reihenfolge
        #data = []
        # for i in range(num):
        #	data.append(num - i)
        #Nachrichtenaktualisierung
        self.view.update_message("Sortierung")
        #Starten Sie die Sortierung
        compare_num = self.sort.start(data, self.view.get_algorithm())
        #Nachrichtenaktualisierung
        self.view.update_message(
            "Die Sortierung ist abgeschlossen! (Vergleich:" + str(compare_num) + ")"
        )
#App-Generierung
app = tkinter.Tk()
app.title("Sortieren")
#Objekterstellung anzeigen
view = View(app)
#Objekterstellung sortieren
sort = Sort(view)
#Controller-Objekterstellung
controller = Controller(view, sort)
#Warten auf den Empfang der Veranstaltung im Mainloop
app.mainloop()
Es gibt verschiedene Sortieralgorithmen. Ich hoffe du kannst es gut gebrauchen.
Ich habe den Sortieralgorithmus zusammengefasst
Recommended Posts