Lösung Merge Sort

This commit is contained in:
Oliver Hofmann 2026-04-28 11:46:36 +02:00
parent 47d1217dcb
commit 88acfb9554
2 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,42 @@
import random
import pygame
from utils.algo_game import Game
from utils.algo_context import AlgoContext
from utils.algo_array import Array
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.ctx = AlgoContext()
self.z = Array(l, self.ctx)
self.finished = False
self.sort_generator = merge_sort_stepwise(self.z, self.ctx)
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,71 @@
from utils.algo_array import Array
from utils.algo_context import AlgoContext
from utils.algo_range import Range
from time import perf_counter as pfc
def merge_sort_stepwise(z: Array, ctx: AlgoContext, l=None, r=None, buffer=None):
if l is None:
l = 0
if r is None:
r = len(z) - 1
if buffer is None:
buffer = Array([0] * len(z), ctx)
if l < r:
m = (l + r) // 2
yield from merge_sort_stepwise(z, ctx, l, m, buffer)
yield from merge_sort_stepwise(z, ctx, m + 1, r, buffer)
yield from merge(z, ctx, l, m, r, buffer)
def merge(z: Array, ctx: AlgoContext, l: int, m: int, r: int, buffer: Array):
i, j, k = l, m + 1, l
while i <= m and j <= r:
if z[i] <= z[j]:
buffer[k] = z[i]
i += 1
else:
buffer[k] = z[j]
j += 1
k += 1
while i <= m:
buffer[k] = z[i]
i += 1
k += 1
while j <= r:
buffer[k] = z[j]
j += 1
k += 1
for k in Range(l, r + 1):
z[k] = buffer[k]
yield z
def merge_sort(z: Array, ctx: AlgoContext):
for _ in merge_sort_stepwise(z, ctx):
pass
def sort_file(filename, sort_func):
ctx = AlgoContext()
z = Array.from_file(filename, ctx)
sort_func(z, ctx)
return z
def analyze_complexity(sort_func, sizes, presorted=False):
ctx = AlgoContext()
for size in sizes:
ctx.reset()
if presorted:
z = Array.sorted(size, ctx)
else:
z = Array.random(size, -100, 100, ctx)
sort_func(z, ctx)
ctx.save_stats(size)
ctx.plot_stats(["comparisons", "writes"])
if __name__ == '__main__':
analyze_complexity(merge_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
for filename in ["data/seq0.txt", "data/seq1.txt", "data/seq2.txt", "data/seq3.txt"]:
print(filename)
start = pfc()
print(sort_file(filename, merge_sort))
print(f"Dauer: {pfc() - start:.4f}s")