├── algorithms ├── __init__.py ├── insertionSort.py ├── bubbleSort.py ├── selectionSort.py ├── countingSort.py ├── heapSort.py ├── quickSort.py └── mergeSort.py ├── img ├── ss1.png ├── ss2.png └── ss3.png ├── .gitignore ├── colors.py ├── README.md └── main.py /algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/ss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FahadulShadhin/sorting-algorithms-visualizer/HEAD/img/ss1.png -------------------------------------------------------------------------------- /img/ss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FahadulShadhin/sorting-algorithms-visualizer/HEAD/img/ss2.png -------------------------------------------------------------------------------- /img/ss3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FahadulShadhin/sorting-algorithms-visualizer/HEAD/img/ss3.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | 3 | # Environments 4 | .env 5 | .venv 6 | env/ 7 | venv/ 8 | ENV/ 9 | env.bak/ 10 | venv.bak/ -------------------------------------------------------------------------------- /colors.py: -------------------------------------------------------------------------------- 1 | DARK_GRAY = '#65696B' 2 | LIGHT_GRAY = '#C4C5BF' 3 | BLUE = '#0CA8F6' 4 | DARK_BLUE = '#4204CC' 5 | WHITE = '#FFFFFF' 6 | BLACK = '#000000' 7 | RED = '#F22810' 8 | YELLOW = '#F7E806' 9 | PINK = '#F50BED' 10 | LIGHT_GREEN = '#05F50E' 11 | PURPLE = '#BF01FB' 12 | -------------------------------------------------------------------------------- /algorithms/insertionSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def insertion_sort(data, drawData, timeTick): 5 | for i in range(len(data)): 6 | temp = data[i] 7 | k = i 8 | while k > 0 and temp < data[k-1]: 9 | data[k] = data[k-1] 10 | k -= 1 11 | data[k] = temp 12 | drawData(data, [YELLOW if x == k or x == i else BLUE for x in range(len(data))]) 13 | time.sleep(timeTick) 14 | 15 | drawData(data, [BLUE for x in range(len(data))]) 16 | -------------------------------------------------------------------------------- /algorithms/bubbleSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def bubble_sort(data, drawData, timeTick): 5 | size = len(data) 6 | for i in range(size-1): 7 | for j in range(size-i-1): 8 | if data[j] > data[j+1]: 9 | data[j], data[j+1] = data[j+1], data[j] 10 | drawData(data, [YELLOW if x == j or x == j+1 else BLUE for x in range(len(data))] ) 11 | time.sleep(timeTick) 12 | 13 | drawData(data, [BLUE for x in range(len(data))]) 14 | -------------------------------------------------------------------------------- /algorithms/selectionSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def selection_sort(data, drawData, timeTick): 5 | for i in range(len(data)-1): 6 | minimum = i 7 | for k in range(i+1, len(data)): 8 | if data[k] < data[minimum]: 9 | minimum = k 10 | 11 | data[minimum], data[i] = data[i], data[minimum] 12 | drawData(data, [YELLOW if x == minimum or x == i else BLUE for x in range(len(data))] ) 13 | time.sleep(timeTick) 14 | 15 | drawData(data, [BLUE for x in range(len(data))]) 16 | -------------------------------------------------------------------------------- /algorithms/countingSort.py: -------------------------------------------------------------------------------- 1 | # Counting sort is not a comperison-based algorithm like the others. 2 | # This algorithm counts the frequency of every unique element in a range. 3 | # If the maximum value of the array is large it is not a good idea to use counting sort. 4 | # But as in this case data[] is generating values between 1 to 150, counting sort works just fine :) 5 | 6 | import time 7 | from colors import * 8 | 9 | def counting_sort(data, drawData, timeTick): 10 | n = max(data) + 1 11 | count = [0] * n 12 | for item in data: 13 | count[item] += 1 14 | 15 | k = 0 16 | for i in range(n): 17 | for j in range(count[i]): 18 | data[k] = i 19 | drawData(data, [BLUE for x in range(len(data))] ) 20 | time.sleep(timeTick) 21 | k += 1 22 | 23 | drawData(data, [BLUE for x in range(len(data))]) 24 | 25 | -------------------------------------------------------------------------------- /algorithms/heapSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def heapify(data, n, i, drawData, timeTick): 5 | largest = i 6 | left = 2*i+1 7 | right = 2*i+2 8 | 9 | if left < n and data[i] < data[left]: 10 | largest = left 11 | 12 | if right < n and data[largest] < data[right]: 13 | largest = right 14 | 15 | if largest != i: 16 | data[i], data[largest] = data[largest], data[i] 17 | heapify(data, n, largest, drawData, timeTick) 18 | 19 | 20 | def heap_sort(data, drawData, timeTick): 21 | n = len(data) 22 | 23 | for i in range(n-1, -1, -1): 24 | heapify(data, n, i, drawData, timeTick) 25 | 26 | for i in range(n-1, 0, -1): 27 | data[i], data[0] = data[0], data[i] 28 | heapify(data, i, 0, drawData, timeTick) 29 | drawData(data, [YELLOW if x == i else BLUE for x in range(n)]) 30 | time.sleep(timeTick) 31 | 32 | drawData(data, [BLUE for x in range(len(data))]) 33 | -------------------------------------------------------------------------------- /algorithms/quickSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def partition(data, start, end, drawData, timeTick): 5 | i = start + 1 6 | pivot = data[start] 7 | 8 | for j in range(start+1, end+1): 9 | if data[j] < pivot: 10 | data[i], data[j] = data[j], data[i] 11 | i+=1 12 | data[start], data[i-1] = data[i-1], data[start] 13 | return i-1 14 | 15 | def quick_sort(data, start, end, drawData, timeTick): 16 | if start < end: 17 | pivot_position = partition(data, start, end, drawData, timeTick) 18 | quick_sort(data, start, pivot_position-1, drawData, timeTick) 19 | quick_sort(data, pivot_position+1, end, drawData, timeTick) 20 | 21 | drawData(data, [PURPLE if x >= start and x < pivot_position else YELLOW if x == pivot_position 22 | else DARK_BLUE if x > pivot_position and x <=end else BLUE for x in range(len(data))]) 23 | time.sleep(timeTick) 24 | 25 | drawData(data, [BLUE for x in range(len(data))]) 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sorting Algorithms Visualizer 2 |

A python application to visualize various sorting algorithms.

3 | 10 |

11 | 12 | ## Implemented Algorithms: 13 | * Bubble Sort 14 | * Insertion Sort 15 | * Selection Sort 16 | * Merge Sort 17 | * Quick Sort 18 | * Heap Sort 19 | * Counting Sort 20 | 21 | ## Built With: 22 | * Python 3.7.7 23 | * Tkinter 8.6 24 | 25 | 26 | 29 | 30 | ## Run It (Python >= 3.5): 31 | - Clone the repository 32 | ```bash 33 | $ git clone https://github.com/FahadulShadhin/Sorting-Algorithms-Visualizer.git 34 | ``` 35 | - Run ```main.py``` from root 36 | ```bash 37 | $ python3 main.py 38 | ``` 39 | -------------------------------------------------------------------------------- /algorithms/mergeSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | from colors import * 3 | 4 | def merge(data, start, mid, end, drawData, timeTick): 5 | p = start 6 | q = mid + 1 7 | tempArray = [] 8 | 9 | for i in range(start, end+1): 10 | if p > mid: 11 | tempArray.append(data[q]) 12 | q+=1 13 | elif q > end: 14 | tempArray.append(data[p]) 15 | p+=1 16 | elif data[p] < data[q]: 17 | tempArray.append(data[p]) 18 | p+=1 19 | else: 20 | tempArray.append(data[q]) 21 | q+=1 22 | 23 | for p in range(len(tempArray)): 24 | data[start] = tempArray[p] 25 | start += 1 26 | 27 | def merge_sort(data, start, end, drawData, timeTick): 28 | if start < end: 29 | mid = int((start + end) / 2) 30 | merge_sort(data, start, mid, drawData, timeTick) 31 | merge_sort(data, mid+1, end, drawData, timeTick) 32 | 33 | merge(data, start, mid, end, drawData, timeTick) 34 | 35 | drawData(data, [PURPLE if x >= start and x < mid else YELLOW if x == mid 36 | else DARK_BLUE if x > mid and x <=end else BLUE for x in range(len(data))]) 37 | time.sleep(timeTick) 38 | 39 | drawData(data, [BLUE for x in range(len(data))]) 40 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from tkinter import ttk 3 | import random 4 | from colors import * 5 | 6 | # Importing algorithms 7 | from algorithms.bubbleSort import bubble_sort 8 | from algorithms.selectionSort import selection_sort 9 | from algorithms.insertionSort import insertion_sort 10 | from algorithms.mergeSort import merge_sort 11 | from algorithms.quickSort import quick_sort 12 | from algorithms.heapSort import heap_sort 13 | from algorithms.countingSort import counting_sort 14 | 15 | 16 | # Main window 17 | window = Tk() 18 | window.title("Sorting Algorithms Visualization") 19 | window.maxsize(1000, 700) 20 | window.config(bg = WHITE) 21 | 22 | 23 | algorithm_name = StringVar() 24 | speed_name = StringVar() 25 | data = [] 26 | algo_list = ['Bubble Sort', 'Insertion Sort', 'Selection Sort', 'Merge Sort', 'Quick Sort', 'Heap Sort', 'Counting Sort'] 27 | speed_list = ['Fast', 'Medium', 'Slow'] 28 | 29 | 30 | # Drawing the numerical array as bars 31 | def drawData(data, colorArray): 32 | canvas.delete("all") 33 | canvas_width = 800 34 | canvas_height = 400 35 | x_width = canvas_width / (len(data) + 1) 36 | offset = 4 37 | spacing = 2 38 | normalizedData = [i / max(data) for i in data] 39 | 40 | for i, height in enumerate(normalizedData): 41 | x0 = i * x_width + offset + spacing 42 | y0 = canvas_height - height * 390 43 | x1 = (i + 1) * x_width + offset 44 | y1 = canvas_height 45 | canvas.create_rectangle(x0, y0, x1, y1, fill=colorArray[i]) 46 | 47 | window.update_idletasks() 48 | 49 | 50 | # Randomly generate array 51 | def generate(): 52 | global data 53 | 54 | data = [] 55 | for i in range(0, 100): 56 | random_value = random.randint(1, 150) 57 | data.append(random_value) 58 | 59 | drawData(data, [BLUE for x in range(len(data))]) 60 | 61 | 62 | def set_speed(): 63 | if speed_menu.get() == 'Slow': 64 | return 0.3 65 | elif speed_menu.get() == 'Medium': 66 | return 0.1 67 | else: 68 | return 0.001 69 | 70 | 71 | def sort(): 72 | global data 73 | timeTick = set_speed() 74 | 75 | if algo_menu.get() == 'Bubble Sort': 76 | bubble_sort(data, drawData, timeTick) 77 | elif algo_menu.get() == 'Selection Sort': 78 | selection_sort(data, drawData, timeTick) 79 | elif algo_menu.get() == 'Insertion Sort': 80 | insertion_sort(data, drawData, timeTick) 81 | elif algo_menu.get() == 'Merge Sort': 82 | merge_sort(data, 0, len(data)-1, drawData, timeTick) 83 | elif algo_menu.get() == 'Quick Sort': 84 | quick_sort(data, 0, len(data)-1, drawData, timeTick) 85 | elif algo_menu.get() == 'Heap Sort': 86 | heap_sort(data, drawData, timeTick) 87 | else: 88 | counting_sort(data, drawData, timeTick) 89 | 90 | 91 | ### User interface ### 92 | UI_frame = Frame(window, width= 900, height=300, bg=WHITE) 93 | UI_frame.grid(row=0, column=0, padx=10, pady=5) 94 | 95 | l1 = Label(UI_frame, text="Algorithm: ", bg=WHITE) 96 | l1.grid(row=0, column=0, padx=10, pady=5, sticky=W) 97 | algo_menu = ttk.Combobox(UI_frame, textvariable=algorithm_name, values=algo_list) 98 | algo_menu.grid(row=0, column=1, padx=5, pady=5) 99 | algo_menu.current(0) 100 | 101 | l2 = Label(UI_frame, text="Sorting Speed: ", bg=WHITE) 102 | l2.grid(row=1, column=0, padx=10, pady=5, sticky=W) 103 | speed_menu = ttk.Combobox(UI_frame, textvariable=speed_name, values=speed_list) 104 | speed_menu.grid(row=1, column=1, padx=5, pady=5) 105 | speed_menu.current(0) 106 | 107 | canvas = Canvas(window, width=800, height=400, bg=WHITE) 108 | canvas.grid(row=1, column=0, padx=10, pady=5) 109 | 110 | b1 = Button(UI_frame, text="Sort", command=sort, bg=LIGHT_GRAY) 111 | b1.grid(row=2, column=1, padx=5, pady=5) 112 | 113 | b3 = Button(UI_frame, text="Generate Array", command=generate, bg=LIGHT_GRAY) 114 | b3.grid(row=2, column=0, padx=5, pady=5) 115 | 116 | 117 | window.mainloop() --------------------------------------------------------------------------------