Merge Sort

This commit is contained in:
Oliver Hofmann 2025-04-01 21:46:18 +02:00
parent 36383991d6
commit 7ced5ed336
4 changed files with 130 additions and 1 deletions

View File

@ -0,0 +1,41 @@
import random
import pygame
from utils.game import Game
from utils.memory_array import MemoryArray
from merge_sorting import merge_sort_stepwise
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
class MergeGame(Game):
def __init__(self):
super().__init__("Merge Game", fps=10, size=(400, 400))
random.seed()
l =list(range(1, 101))
random.shuffle(l)
self.z = MemoryArray(l)
self.finished = False
self.sort_generator = merge_sort_stepwise(self.z)
def update_game(self):
if not self.finished:
try:
next(self.sort_generator)
except StopIteration:
self.finished = True
return True
def draw_game(self):
self.screen.fill(WHITE)
for i, cell in enumerate(self.z):
x = 50 + i*3
y = 350 - cell.value * 3
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
super().draw_game()
if __name__ == "__main__":
s = MergeGame()
s.run()

View File

@ -0,0 +1,85 @@
from utils.memory_array import MemoryArray
from utils.memory_cell import MemoryCell
from utils.memory_manager import MemoryManager
from utils.memory_range import mrange
from utils.literal import Literal
def merge_sort_stepwise(z: MemoryArray, l: Literal = None, r: Literal = None, buffer: MemoryArray = None):
if l is None:
l = Literal(0)
if r is None:
r = z.length().pred()
if buffer is None:
buffer = MemoryArray(z.length())
if l < r:
m = Literal((int(l) + int(r)) // 2)
yield from merge_sort_stepwise(z, l, m, buffer)
yield from merge_sort_stepwise(z, m.succ(), r, buffer)
yield from merge(z, l, m, r, buffer)
def merge(z: MemoryArray, l: Literal, m: Literal, r: Literal, buffer: MemoryArray):
i = MemoryCell(l)
j = MemoryCell(m.succ())
k = MemoryCell(l)
while i <= m and j <= r:
if z[i] <= z[j]:
buffer[k].set(z[i])
i = i.succ()
else:
buffer[k].set(z[j])
j = j.succ()
k = k.succ()
while i <= m:
buffer[k].set(z[i])
i = i.succ()
k = k.succ()
while j <= r:
buffer[k].set(z[j])
j = j.succ()
k = k.succ()
for k in mrange(l, r.succ()):
z[k].set(buffer[k])
yield z
def merge_sort(z: MemoryArray):
sort_generator = merge_sort_stepwise(z)
while True:
try:
next(sort_generator)
except StopIteration:
break
# print(len(z), z.count_compares(), MemoryManager.get_instance().count_compares())
def sort_file(filename, sort_func):
z = MemoryArray.create_array_from_file(filename)
sort_func(z)
return z
def analyze_complexity(sort_func, sizes, presorted=False):
"""
Analysiert die Komplexität einer Sortierfunktion.
:param sort_func: Die Funktion, die analysiert wird.
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
"""
for size in sizes:
MemoryManager.purge() # Speicher zurücksetzen
if presorted:
random_array = MemoryArray.create_sorted_array(size)
else:
random_array = MemoryArray.create_random_array(size, -100, 100)
sort_func(random_array)
MemoryManager.save_stats(size)
MemoryManager.plot_stats(["cells", "compares", "writes"])
def swap(z: MemoryArray, i: int, j: int):
tmp = z[Literal(i)].value
z[Literal(i)] = z[Literal(j)]
z[Literal(j)].set(tmp)
if __name__ == '__main__':
analyze_complexity(merge_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# analyze_complexity(merge_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)

View File

@ -58,6 +58,10 @@ class MemoryArray:
"""Gibt die Größe des Speicherarrays zurück.""" """Gibt die Größe des Speicherarrays zurück."""
return Literal(self.size) return Literal(self.size)
def count_compares(self):
return sum([cell.compare_count for cell in self.cells])
def reset_counters(self): def reset_counters(self):
"""Setzt alle Zähler auf 0 zurück.""" """Setzt alle Zähler auf 0 zurück."""
for cell in self.cells: for cell in self.cells:

View File

@ -1,6 +1,5 @@
from utils.memory_array import MemoryArray from utils.memory_array import MemoryArray
from utils.memory_cell import MemoryCell from utils.memory_cell import MemoryCell
from utils.constants import MIN_VALUE
from utils.memory_manager import MemoryManager from utils.memory_manager import MemoryManager
from utils.memory_range import mrange from utils.memory_range import mrange
from utils.literal import Literal from utils.literal import Literal