diff --git a/SortingAlgorithms/.DS_Store b/SortingAlgorithms/.DS_Store new file mode 100644 index 0000000..315eb4a Binary files /dev/null and b/SortingAlgorithms/.DS_Store differ diff --git a/SortingAlgorithms/README.md b/SortingAlgorithms/README.md new file mode 100644 index 0000000..f5e82c1 --- /dev/null +++ b/SortingAlgorithms/README.md @@ -0,0 +1,33 @@ +# SortingAlgorithms + +## BubbleSort + +

+ +

+ + +## InsertionSort + +

+ +

+ + +## MergeSort + +

+ +

+ +## QuickSort + +

+ +

+ +## SelectionSort + +

+ +

diff --git a/SortingAlgorithms/gui.py b/SortingAlgorithms/gui.py new file mode 100644 index 0000000..1dcf82c --- /dev/null +++ b/SortingAlgorithms/gui.py @@ -0,0 +1,104 @@ +import matplotlib.animation as animation +import matplotlib.pyplot as plt +from tkinter import messagebox +from sort import Algorithms +import tkinter as tk +import random +import time + + +class Window(tk.Tk): + def __init__(self): + super().__init__() + self.title("Sorting Algorithms - Clever Code") + # self.resizable(False, False) + + self.frame = tk.Frame() + self.frame.pack() + self.n_label = tk.Label(self.frame, text="n:", font=("Cascadia Code", "15")) + self.n_label.grid(row=0, column=0, padx=10, pady=10) + self.n_entry = tk.Entry(self.frame, justify="center", font=("Cascadia Code", "15")) + self.n_entry.grid(row=0, column=1, padx=10, sticky="E") + + self.sort_frame = tk.Frame() + self.sort_frame.pack() + self.radio_value = tk.IntVar() + self.radio_value.set(-1) + self.bubble_sort = tk.Radiobutton(self.sort_frame, text="BubbleSort", variable=self.radio_value, value=0) + self.bubble_sort.grid(row=0, column=0, padx=10, sticky="W") + self.insertion_sort = tk.Radiobutton(self.sort_frame, text="InsertionSort", variable=self.radio_value, value=1) + self.insertion_sort.grid(row=0, column=1, padx=10, sticky="W") + self.merge_sort = tk.Radiobutton(self.sort_frame, text="MergeSort", variable=self.radio_value, value=2) + self.merge_sort.grid(row=1, column=0, padx=10, sticky="W") + self.quick_sort = tk.Radiobutton(self.sort_frame, text="QuickSort", variable=self.radio_value, value=3) + self.quick_sort.grid(row=1, column=1, padx=10, sticky="W") + self.selection_sort = tk.Radiobutton(self.sort_frame, text="SelectionSort", variable=self.radio_value, value=4) + self.selection_sort.grid(row=2, columnspan=2, padx=10) + + self.button_frame = tk.Frame() + self.button_frame.pack() + self.reset_button = tk.Button(self.button_frame, text="Reset", font=("Cascadia Code", "15"), command=self.resetWindow) + self.reset_button.grid(row=0, column=0, padx=10, pady=10, sticky="WE") + self.start_button = tk.Button(self.button_frame, text="Start", font=("Cascadia Code", "15"), command=self.setAlgorithm) + self.start_button.grid(row=0, column=1, padx=10, pady=10, sticky="WE") + + def resetWindow(self): + self.n_entry.delete(0, tk.END) + self.radio_value.set(-1) + + def __checkAll(self): + try: + if self.radio_value.get() in [i for i in range(0, 5)] and int(self.n_entry.get()): + return True + except ValueError: + return False + + def setAlgorithm(self): + if self.__checkAll(): + N = int(self.n_entry.get()) + A = [x + 1 for x in range(N)] + random.seed(time.time()) + random.shuffle(A) + + algo = Algorithms() + if self.radio_value.get() == 0: + self.title = "BubbleSort" + self.generator = algo.bubblesort(A) + elif self.radio_value.get() == 1: + self.title = "InsertionSort" + self.generator = algo.insertionsort(A) + elif self.radio_value.get() == 2: + self.title = "MergeSort" + self.generator = algo.mergesort(A, 0, N - 1) + elif self.radio_value.get() == 3: + self.title = "QuickSort" + self.generator = algo.quicksort(A, 0, N - 1) + else: + self.title = "SelectionSort" + self.generator = algo.selectionsort(A) + + self.showFigure(A, N) + else: + messagebox.showerror("Si รจ verificato un errore", "Valori Inseriti Non Validi!") + + def updateFigure(self, A, rects, iteration): + for rect, val in zip(rects, A): + rect.set_height(val) + iteration[0] += 1 + self.text.set_text("# of Operations: {}".format(iteration[0])) + + def showFigure(self, A, N): + fig, ax = plt.subplots() + ax.set_title(self.title) + bar_rects = ax.bar(range(len(A)), A, align="edge") + ax.set_xlim(0, N) + ax.set_ylim(0, int(1.07 * N)) + self.text = ax.text(0.02, 0.95, "", transform=ax.transAxes) + + iteration = [0] + anim = animation.FuncAnimation(fig, func=self.updateFigure, fargs=(bar_rects, iteration), frames=self.generator, interval=1, repeat=False) + plt.show() + +if __name__ == "__main__": + window = Window() + window.mainloop() \ No newline at end of file diff --git a/SortingAlgorithms/imgs/BubbleSort.png b/SortingAlgorithms/imgs/BubbleSort.png new file mode 100644 index 0000000..c7aad25 Binary files /dev/null and b/SortingAlgorithms/imgs/BubbleSort.png differ diff --git a/SortingAlgorithms/imgs/InsertionSort.png b/SortingAlgorithms/imgs/InsertionSort.png new file mode 100644 index 0000000..51892a9 Binary files /dev/null and b/SortingAlgorithms/imgs/InsertionSort.png differ diff --git a/SortingAlgorithms/imgs/MergeSort.png b/SortingAlgorithms/imgs/MergeSort.png new file mode 100644 index 0000000..4b0b4b2 Binary files /dev/null and b/SortingAlgorithms/imgs/MergeSort.png differ diff --git a/SortingAlgorithms/imgs/QuickSort.png b/SortingAlgorithms/imgs/QuickSort.png new file mode 100644 index 0000000..74c0d45 Binary files /dev/null and b/SortingAlgorithms/imgs/QuickSort.png differ diff --git a/SortingAlgorithms/imgs/SelectionSort.png b/SortingAlgorithms/imgs/SelectionSort.png new file mode 100644 index 0000000..dfe100e Binary files /dev/null and b/SortingAlgorithms/imgs/SelectionSort.png differ diff --git a/SortingAlgorithms/imgs/gui.png b/SortingAlgorithms/imgs/gui.png new file mode 100644 index 0000000..08a290c Binary files /dev/null and b/SortingAlgorithms/imgs/gui.png differ diff --git a/SortingAlgorithms/requirements.txt b/SortingAlgorithms/requirements.txt new file mode 100644 index 0000000..fec370b --- /dev/null +++ b/SortingAlgorithms/requirements.txt @@ -0,0 +1 @@ +matplotlib==3.5.1 diff --git a/SortingAlgorithms/sort.py b/SortingAlgorithms/sort.py new file mode 100644 index 0000000..ab6592c --- /dev/null +++ b/SortingAlgorithms/sort.py @@ -0,0 +1,97 @@ +class Algorithms: + def swap(self, A, i, j): + if i != j: + A[i], A[j] = A[j], A[i] + + def bubblesort(self, A): + if len(A) == 1: + return + + swapped = True + for i in range(len(A) - 1): + if not swapped: + break + swapped = False + for j in range(len(A) - 1 - i): + if A[j] > A[j + 1]: + self.swap(A, j, j + 1) + swapped = True + yield A + + def insertionsort(self, A): + for i in range(1, len(A)): + j = i + while j > 0 and A[j] < A[j - 1]: + self.swap(A, j, j - 1) + j -= 1 + yield A + + def mergesort(self, A, start, end): + if end <= start: + return + + mid = start + ((end - start + 1) // 2) - 1 + yield from self.mergesort(A, start, mid) + yield from self.mergesort(A, mid + 1, end) + yield from self.merge(A, start, mid, end) + yield A + + def merge(self, A, start, mid, end): + merged = [] + leftIdx = start + rightIdx = mid + 1 + + while leftIdx <= mid and rightIdx <= end: + if A[leftIdx] < A[rightIdx]: + merged.append(A[leftIdx]) + leftIdx += 1 + else: + merged.append(A[rightIdx]) + rightIdx += 1 + + while leftIdx <= mid: + merged.append(A[leftIdx]) + leftIdx += 1 + + while rightIdx <= end: + merged.append(A[rightIdx]) + rightIdx += 1 + + for i, sorted_val in enumerate(merged): + A[start + i] = sorted_val + yield A + + def quicksort(self, A, start, end): + if start >= end: + return + + pivot = A[end] + pivotIdx = start + + for i in range(start, end): + if A[i] < pivot: + self.swap(A, i, pivotIdx) + pivotIdx += 1 + yield A + self.swap(A, end, pivotIdx) + yield A + + yield from self.quicksort(A, start, pivotIdx - 1) + yield from self.quicksort(A, pivotIdx + 1, end) + + + def selectionsort(self, A): + if len(A) == 1: + return + + for i in range(len(A)): + # Find minimum unsorted value. + minVal = A[i] + minIdx = i + for j in range(i, len(A)): + if A[j] < minVal: + minVal = A[j] + minIdx = j + yield A + self.swap(A, i, minIdx) + yield A \ No newline at end of file diff --git a/SortingAlgorithms/ui.py b/SortingAlgorithms/ui.py new file mode 100755 index 0000000..77fe98c --- /dev/null +++ b/SortingAlgorithms/ui.py @@ -0,0 +1,78 @@ +import matplotlib.animation as animation +import matplotlib.pyplot as plt +from sort import Algorithms +import random +import time + + +def main(): + while True: + N = int(input("Enter number of integers: ")) + if N > 0: + while True: + try: + method = int(input("Enter sorting method:\n(1) BubbleSort\n(2) InsertionSort\n(3) MergeSort\n(4) QuickSort\n(5) SelectionSort\n(0) Exit\n> ")) + if method in [i for i in range(0, 6)]: + + # init random list A + A = [x + 1 for x in range(N)] + random.seed(time.time()) + random.shuffle(A) + + algo = Algorithms() + if method == 0: + print("Bye.") + exit() + elif method == 1: + title = "BubbleSort" + generator = algo.bubblesort(A) + elif method == 2: + title = "InsertionSort" + generator = algo.insertionsort(A) + elif method == 3: + title = "MergeSort" + generator = algo.mergesort(A, 0, N - 1) + elif method == 4: + title = "QuickSort" + generator = algo.quicksort(A, 0, N - 1) + elif method == 5: + title = "SelectionSort" + generator = algo.selectionsort(A) + + print(f"You selected {title}") + output(A, N, title, generator) + print("Bye.") + exit() + else: + print("You must enter a number between 0 and 5... Try Again!") + except Exception as e: + print(f"Error: {e}... Try Again!") + else: + print("You must enter a number > 0... Try again!") + + +def update_fig(A, rects, iteration, text): + for rect, val in zip(rects, A): + rect.set_height(val) + iteration[0] += 1 + text.set_text("# of Operations: {}".format(iteration[0])) + +def output(A, N, title, generator): + fig, ax = plt.subplots() + ax.set_title(title) + + bar_rects = ax.bar(range(len(A)), A, align="edge") + ax.set_xlim(0, N) + ax.set_ylim(0, int(1.07 * N)) + + text = ax.text(0.02, 0.95, "", transform=ax.transAxes) + + iteration = [0] + anim = animation.FuncAnimation(fig, func=update_fig, + fargs=(bar_rects, iteration, text), frames=generator, interval=1, + repeat=False) + plt.show() + + +if __name__ == "__main__": + main() \ No newline at end of file