-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisualizer.py
More file actions
148 lines (124 loc) · 4.72 KB
/
Copy pathvisualizer.py
File metadata and controls
148 lines (124 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
import argparse
from typing import List, Generator, Tuple
def bubble_sort(arr: List[int]) -> Generator[Tuple[List[int], int, int], None, None]:
n = len(arr)
for i in range(n):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
yield arr, j, j + 1
def selection_sort(arr: List[int]) -> Generator[Tuple[List[int], int, int], None, None]:
n = len(arr)
for i in range(n):
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
yield arr, i, j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
yield arr, i, min_idx
def insertion_sort(arr: List[int]) -> Generator[Tuple[List[int], int, int], None, None]:
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
yield arr, j + 1, i
arr[j + 1] = key
yield arr, j + 1, i
def quick_sort(arr: List[int], low: int = 0, high: int = None) -> Generator[Tuple[List[int], int, int], None, None]:
if high is None:
high = len(arr) - 1
if low < high:
pivot_idx = yield from partition(arr, low, high)
yield from quick_sort(arr, low, pivot_idx - 1)
yield from quick_sort(arr, pivot_idx + 1, high)
def partition(arr: List[int], low: int, high: int) -> Generator[Tuple[List[int], int, int], None, int]:
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
yield arr, i, j
arr[i + 1], arr[high] = arr[high], arr[i + 1]
yield arr, i + 1, high
return i + 1
def merge_sort(arr: List[int], left: int = 0, right: int = None) -> Generator[Tuple[List[int], int, int], None, None]:
if right is None:
right = len(arr) - 1
if left < right:
mid = (left + right) // 2
yield from merge_sort(arr, left, mid)
yield from merge_sort(arr, mid + 1, right)
yield from merge(arr, left, mid, right)
def merge(arr: List[int], left: int, mid: int, right: int) -> Generator[Tuple[List[int], int, int], None, None]:
left_copy = arr[left:mid + 1]
right_copy = arr[mid + 1:right + 1]
i = j = 0
k = left
while i < len(left_copy) and j < len(right_copy):
if left_copy[i] <= right_copy[j]:
arr[k] = left_copy[i]
i += 1
else:
arr[k] = right_copy[j]
j += 1
k += 1
yield arr, k, k - 1
while i < len(left_copy):
arr[k] = left_copy[i]
i += 1
k += 1
yield arr, k, k - 1
while j < len(right_copy):
arr[k] = right_copy[j]
j += 1
k += 1
yield arr, k, k - 1
ALGORITHMS = {
"bubble": bubble_sort,
"selection": selection_sort,
"insertion": insertion_sort,
"quick": quick_sort,
"merge": merge_sort,
}
def animate(algorithm_name: str, size: int = 50, interval: int = 10):
data = [random.randint(1, 100) for _ in range(size)]
generator = ALGORITHMS[algorithm_name](data)
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_title(f"{algorithm_name.title()} Sort")
bar_container = ax.bar(range(len(data)), data, color="steelblue")
ax.set_xlim(-1, len(data))
steps_done = [0]
def update(_):
try:
arr, i, j = next(generator)
for bar, val in zip(bar_container, arr):
bar.set_height(val)
for idx, bar in enumerate(bar_container):
if idx in (i, j):
bar.set_color("crimson")
elif idx <= steps_done[0] and algorithm_name in ("bubble", "selection", "insertion"):
bar.set_color("limegreen")
else:
bar.set_color("steelblue")
steps_done[0] += 1
except StopIteration:
for bar in bar_container:
bar.set_color("limegreen")
return bar_container
ani = animation.FuncAnimation(fig, update, frames=range(1000), interval=interval, blit=False, repeat=False)
plt.tight_layout()
plt.show()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Visualize sorting algorithms")
parser.add_argument("algorithm", choices=list(ALGORITHMS.keys()), help="Sorting algorithm")
parser.add_argument("--size", type=int, default=50, help="Number of elements to sort")
parser.add_argument("--interval", type=int, default=10, help="Animation speed (ms per frame)")
args = parser.parse_args()
animate(args.algorithm, args.size, args.interval)