├── README.md ├── bubbleSort.py ├── mergesort.py ├── quicksort.py ├── s1.jpg ├── s2.jpg ├── s3.jpg ├── s4.jpg ├── s5.jpg ├── s6.jpg └── sort.py /README.md: -------------------------------------------------------------------------------- 1 | # Sortex 2 | 3 | ### A comprehensive and insightful sorting visualizer 4 | 5 | ### Demo Video: 6 | 7 | https://user-images.githubusercontent.com/64016811/125228100-caa8fc00-e2f1-11eb-87e2-106aa02282f9.mp4 8 | 9 | ### Some Screenshots: 10 | 11 | ![a1](https://user-images.githubusercontent.com/64016811/125232994-5d01cd80-e2fb-11eb-8d18-6b571d791e1a.jpg) 12 | ![a2](https://user-images.githubusercontent.com/64016811/125232999-5ecb9100-e2fb-11eb-9655-ec5f8237b02c.jpg) 13 | 14 | 15 | -------------------------------------------------------------------------------- /bubbleSort.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | def bubble_sort(data, drawData, timeTick): 4 | for _ in range(len(data)-1): 5 | for j in range(len(data)-1): 6 | if data[j] > data[j+1]: 7 | data[j], data[j+1] = data[j+1], data[j] 8 | drawData(data, ['green' if x == j or x == j+1 else 'red' for x in range(len(data))] ) 9 | time.sleep(timeTick) 10 | drawData(data, ['green' for x in range(len(data))]) -------------------------------------------------------------------------------- /mergesort.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | def merge_sort(data, drawData, timeTick): 4 | merge_sort_alg(data,0, len(data)-1, drawData, timeTick) 5 | 6 | 7 | def merge_sort_alg(data, left, right, drawData, timeTick): 8 | if left < right: 9 | middle = (left + right) // 2 10 | merge_sort_alg(data, left, middle, drawData, timeTick) 11 | merge_sort_alg(data, middle+1, right, drawData, timeTick) 12 | merge(data, left, middle, right, drawData, timeTick) 13 | 14 | def merge(data, left, middle, right, drawData, timeTick): 15 | drawData(data, getColorArray(len(data), left, middle, right)) 16 | time.sleep(timeTick) 17 | 18 | leftPart = data[left:middle+1] 19 | rightPart = data[middle+1: right+1] 20 | 21 | leftIdx = rightIdx = 0 22 | 23 | for dataIdx in range(left, right+1): 24 | if leftIdx < len(leftPart) and rightIdx < len(rightPart): 25 | if leftPart[leftIdx] <= rightPart[rightIdx]: 26 | data[dataIdx] = leftPart[leftIdx] 27 | leftIdx += 1 28 | else: 29 | data[dataIdx] = rightPart[rightIdx] 30 | rightIdx += 1 31 | 32 | elif leftIdx < len(leftPart): 33 | data[dataIdx] = leftPart[leftIdx] 34 | leftIdx += 1 35 | else: 36 | data[dataIdx] = rightPart[rightIdx] 37 | rightIdx += 1 38 | 39 | drawData(data, ["green" if x >= left and x <= right else "white" for x in range(len(data))]) 40 | time.sleep(timeTick) 41 | 42 | def getColorArray(leght, left, middle, right): 43 | colorArray = [] 44 | 45 | for i in range(leght): 46 | if i >= left and i <= right: 47 | if i >= left and i <= middle: 48 | colorArray.append("yellow") 49 | else: 50 | colorArray.append("pink") 51 | else: 52 | colorArray.append("white") 53 | 54 | return colorArray -------------------------------------------------------------------------------- /quicksort.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | def partition(data, head, tail, drawData, timeTick): 4 | border = head 5 | pivot = data[tail] 6 | 7 | drawData(data, getColorArray(len(data), head, tail, border, border)) 8 | time.sleep(timeTick) 9 | 10 | for j in range(head, tail): 11 | if data[j] < pivot: 12 | drawData(data, getColorArray(len(data), head, tail, border, j, True)) 13 | time.sleep(timeTick) 14 | 15 | data[border], data[j] = data[j], data[border] 16 | border += 1 17 | 18 | drawData(data, getColorArray(len(data), head, tail, border, j)) 19 | time.sleep(timeTick) 20 | 21 | 22 | #swap pivot with border value 23 | drawData(data, getColorArray(len(data), head, tail, border, tail, True)) 24 | time.sleep(timeTick) 25 | 26 | data[border], data[tail] = data[tail], data[border] 27 | 28 | return border 29 | 30 | def quick_sort(data, head, tail, drawData, timeTick): 31 | if head < tail: 32 | partitionIdx = partition(data, head, tail, drawData, timeTick) 33 | 34 | #LEFT PARTITION 35 | quick_sort(data, head, partitionIdx-1, drawData, timeTick) 36 | 37 | #RIGHT PARTITION 38 | quick_sort(data, partitionIdx+1, tail, drawData, timeTick) 39 | 40 | 41 | def getColorArray(dataLen, head, tail, border, currIdx, isSwaping = False): 42 | colorArray = [] 43 | for i in range(dataLen): 44 | #base coloring 45 | if i >= head and i <= tail: 46 | colorArray.append('gray') 47 | else: 48 | colorArray.append('white') 49 | 50 | if i == tail: 51 | colorArray[i] = 'blue' 52 | elif i == border: 53 | colorArray[i] = 'red' 54 | elif i == currIdx: 55 | colorArray[i] = 'yellow' 56 | 57 | if isSwaping: 58 | if i == border or i == currIdx: 59 | colorArray[i] = 'green' 60 | 61 | return colorArray -------------------------------------------------------------------------------- /s1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s1.jpg -------------------------------------------------------------------------------- /s2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s2.jpg -------------------------------------------------------------------------------- /s3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s3.jpg -------------------------------------------------------------------------------- /s4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s4.jpg -------------------------------------------------------------------------------- /s5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s5.jpg -------------------------------------------------------------------------------- /s6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MainakRepositor/Sortex/2095587074c4866a365a3394f566faa896b39d46/s6.jpg -------------------------------------------------------------------------------- /sort.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from tkinter import ttk 3 | import random 4 | from bubbleSort import bubble_sort 5 | from quicksort import quick_sort 6 | from mergesort import merge_sort 7 | 8 | root = Tk() 9 | root.title('SORTEX : Sorting Visualiser') 10 | root.maxsize(650, 600) 11 | root.config(bg='blue') 12 | 13 | #variables 14 | selected_alg = StringVar() 15 | data = [] 16 | 17 | #function 18 | def drawData(data, colorArray): 19 | canvas.delete("all") 20 | c_height = 380 21 | c_width = 600 22 | x_width = c_width / (len(data) + 1) 23 | offset = 30 24 | spacing = 10 25 | normalizedData = [ i / max(data) for i in data] 26 | for i, height in enumerate(normalizedData): 27 | #top left 28 | x0 = i * x_width + offset + spacing 29 | y0 = c_height - height * 340 30 | #bottom right 31 | x1 = (i + 1) * x_width + offset 32 | y1 = c_height 33 | 34 | canvas.create_rectangle(x0, y0, x1, y1, fill=colorArray[i]) 35 | canvas.create_text(x0+2, y0, anchor=SW, text=str(data[i])) 36 | 37 | root.update_idletasks() 38 | 39 | 40 | def Generate(): 41 | global data 42 | 43 | minVal = int(minEntry.get()) 44 | maxVal = int(maxEntry.get()) 45 | size = int(sizeEntry.get()) 46 | 47 | data = [] 48 | for _ in range(size): 49 | data.append(random.randrange(minVal, maxVal+1)) 50 | 51 | drawData(data, ['red' for x in range(len(data))]) 52 | 53 | def StartAlgorithm(): 54 | global data 55 | if not data: return 56 | 57 | if algMenu.get() == 'Quick Sort': 58 | quick_sort(data, 0, len(data)-1, drawData, speedScale.get()) 59 | 60 | elif algMenu.get() == 'Bubble Sort': 61 | bubble_sort(data, drawData, speedScale.get()) 62 | 63 | elif algMenu.get() == 'Merge Sort': 64 | merge_sort(data, drawData, speedScale.get()) 65 | 66 | drawData(data, ['green' for x in range(len(data))]) 67 | 68 | 69 | #frame / base lauout 70 | UI_frame = Frame(root, width= 600, height=200, bg='grey') 71 | UI_frame.grid(row=0, column=0, padx=10, pady=5) 72 | 73 | canvas = Canvas(root, width=600, height=380, bg='white') 74 | canvas.grid(row=1, column=0, padx=10, pady=5) 75 | 76 | #User Interface Area 77 | #Row[0] 78 | Label(UI_frame, text="Algorithm: ", fg="white",bg='grey',font=('times new roman',16,'bold')).grid(row=0, column=0, padx=5, pady=2, sticky=W) 79 | algMenu = ttk.Combobox(UI_frame, textvariable=selected_alg, values=['Bubble Sort', 'Quick Sort', 'Merge Sort'],state="readonly",font=('times new roman',12,'bold')) 80 | algMenu.grid(row=0, column=1, padx=1, pady=1) 81 | algMenu.current(0) 82 | 83 | speedScale = Scale(UI_frame, from_=0.1, to=5.0, length=200, digits=2, resolution=0.2, orient=HORIZONTAL, label="Select Speed [s]") 84 | speedScale.grid(row=0, column=2, padx=5, pady=5) 85 | Button(UI_frame, text="START", command=StartAlgorithm, font=('times new roman',16,'bold'), fg='white',bg='green').grid(row=0, column=3, padx=5, pady=5) 86 | 87 | #Row[1] 88 | sizeEntry = Scale(UI_frame, from_=3, to=25, resolution=1, orient=HORIZONTAL, label="Data Size") 89 | sizeEntry.grid(row=1, column=0, padx=5, pady=5) 90 | 91 | minEntry = Scale(UI_frame, from_=0, to=10, resolution=1, orient=HORIZONTAL, label="Min Value") 92 | minEntry.grid(row=1, column=1, padx=5, pady=5) 93 | 94 | maxEntry = Scale(UI_frame, from_=10, to=100, resolution=1, orient=HORIZONTAL, label="Max Value") 95 | maxEntry.grid(row=1, column=2, padx=5, pady=5) 96 | 97 | Button(UI_frame, text="Generate", command=Generate,font=('times new roman',13,'bold'), bg='yellow',fg='black').grid(row=1, column=3, padx=5, pady=5) 98 | 99 | root.mainloop() 100 | 101 | --------------------------------------------------------------------------------