Visualisieren Sie, wie Daten mit Pythons Tkinter sortiert werden "Das war's!" Es ist ein Code, der zu sein scheint. before 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