-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7ca4d10
Showing
9 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from tkinter import* | ||
from tkinter import ttk | ||
import random | ||
from src.quicksort import quick_sort | ||
from src.insertionsort import insertion_sort | ||
from src.bubbleSort import bubble_sort | ||
from src.selectionsort import selection_sort | ||
from src.mergesort import merge_sort | ||
|
||
def main(): | ||
root = Tk() | ||
root.title('Sorting Algorithm Visualisation') | ||
root.maxsize(1800,1200) | ||
root.config(bg='black') | ||
|
||
#variables | ||
selected_alg = StringVar() | ||
data = [] | ||
|
||
def drawData(data,colorArray): | ||
canvas.delete("all") | ||
c_height = 650 | ||
c_width = 1200 | ||
x_width = c_width / (len(data) + 1) | ||
offset = 30 | ||
spacing = 5 | ||
normalizedData = [i / max(data) for i in data] | ||
|
||
for i,height in enumerate(normalizedData): | ||
#top left | ||
x0 = i * x_width + offset + spacing | ||
y0 = c_height - height * 600 | ||
#bottom right | ||
x1 = (i + 1) * x_width + offset | ||
y1 = c_height | ||
|
||
canvas.create_rectangle(x0,y0,x1,y1, fill=colorArray[i]) | ||
canvas.create_text(x0+2, y0, anchor=SW, text=str(data[i])) | ||
root.update_idletasks() | ||
|
||
def Generate(): | ||
global data | ||
minVal = int(minEntry.get()) | ||
maxVal = int(maxEntry.get()) | ||
size = int(sizeEntry.get()) | ||
|
||
data = [] | ||
|
||
for _ in range(size): | ||
data.append(random.randrange(minVal,maxVal+1)) | ||
drawData(data,['red' for x in range(len(data))]) # | ||
|
||
def StartAlgorithm(): | ||
global data | ||
if not data: return | ||
|
||
|
||
if algMenu.get() == 'Bubble Sort': | ||
bubble_sort(data,drawData,speedScale.get()) | ||
|
||
elif algMenu.get() == 'Selection Sort': | ||
selection_sort(data,drawData,speedScale.get()) | ||
|
||
elif algMenu.get() == 'Insertion Sort': | ||
insertion_sort(data,drawData,speedScale.get()) | ||
|
||
elif algMenu.get() == 'Quick Sort': | ||
quick_sort(data,0,len(data)-1,drawData,speedScale.get()) | ||
|
||
elif algMenu.get() == 'Merge Sort': | ||
merge_sort(data, drawData, speedScale.get()) | ||
|
||
drawData(data,['green' for x in range(len(data))]) | ||
|
||
#frame / base layout | ||
UI_frame = Frame(root, width=1200, height=400, bg='grey') | ||
UI_frame.grid(row=0, column=0, padx=10, pady=5) | ||
|
||
canvas = Canvas(root, width=1200, height=650, bg='white') | ||
canvas.grid(row = 1, column = 0, padx=0,pady=0) | ||
|
||
#User interface area | ||
#Row[0] | ||
Label(UI_frame, text='Algorithm : ', bg='grey').grid(row=0, column=0, padx=5, pady=5, sticky=W) | ||
algMenu = ttk.Combobox(UI_frame,textvariable=selected_alg, values=['Quick Sort','Bubble Sort','Merge Sort','Selection Sort','Insertion Sort']) | ||
algMenu.grid(row=0, column=1, padx=0, pady=5) | ||
algMenu.current(0) | ||
|
||
speedScale = Scale(UI_frame, from_= 0.01, to=10.0, length=200,digits=4, resolution=0.2,orient=HORIZONTAL, label="Select speed [s]") | ||
speedScale.grid(row=0, column=2, padx = 5, pady = 5) | ||
Button(UI_frame, text='Start', command=StartAlgorithm, bg='red').grid(row=0, column=3,padx=5, pady=5) | ||
|
||
#Row[1] | ||
sizeEntry = Scale(UI_frame, from_= 3, to=100, resolution=1,orient=HORIZONTAL, label="Data Size") | ||
sizeEntry.grid(row = 1, column=0, padx=5, pady=5) | ||
|
||
minEntry = Scale(UI_frame, from_= 0, to=20, resolution=1,orient=HORIZONTAL, label="Min Value") | ||
minEntry.grid(row = 1, column=1, padx=5, pady=5) | ||
|
||
maxEntry = Scale(UI_frame, from_= 3, to=100, resolution=1,orient=HORIZONTAL, label="Max Value") | ||
maxEntry.grid(row = 1, column=2, padx=5, pady=5) | ||
|
||
Button(UI_frame, text='Generate', command=Generate, bg='yellow').grid(row=1, column=3,padx=5, pady=5) | ||
|
||
root.mainloop() | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import time | ||
|
||
def bubble_sort(data,drawData,timeTick): | ||
for _ in range(len(data) - 1): | ||
for j in range(len(data) - 1): | ||
if data[j] > data[j+1]: | ||
data[j] , data[j+1] = data[j+1], data[j] | ||
drawData(data,['green' if x == j or x == j+1 else 'red' for x in range(len(data))]) | ||
time.sleep(timeTick / 100) | ||
drawData(data, ['green' for x in range(len(data))]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import time | ||
|
||
def heapSort(array,drawData,timeTick): | ||
buildMaxHeap(array) | ||
for endIdx in reversed(range(1, len(array))): | ||
swap(0, endIdx, array) | ||
siftDown(0, endIdx - 1, array) | ||
return array | ||
|
||
def buildMaxHeap(array): | ||
firstParentIdx = (len(array) - 2) // 2 | ||
for currentIdx in reversed(range(firstParentIdx + 1)): | ||
siftDown(currentIdx, len(array) - 1, array) | ||
|
||
def siftDown(currentIdx, endIdx, heap): | ||
childOneIdx = currentIdx * 2 + 1 | ||
while childOneIdx <= endIdx: | ||
childTwoIdx = currentIdx * 2 + 2 if currentIdx * 2 + 2 <= endIdx else -1 | ||
if childTwoIdx > -1 and heap[childTwoIdx] > heap[childOneIdx]: | ||
idxToSwap = childTwoIdx | ||
else: | ||
idxToSwap = childOneIdx | ||
if heap[idxToSwap] > heap[currentIdx]: | ||
swap(currentIdx, idxToSwap, heap) | ||
currentIdx = idxToSwap | ||
childOneIdx = currentIdx * 2 + 1 | ||
else: | ||
return | ||
def swap(i, j, array): | ||
array[i], array[j] = array[j], array[i] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import time | ||
|
||
|
||
def insertion_sort(data,drawData,timeTick): | ||
for i in range(1,len(data)): | ||
key = data[i] | ||
j = i-1 | ||
while j >= 0 and data[j] > key: | ||
data[j+1] = data[j] | ||
j -= 1 | ||
drawData(data,['green' if x == j or x == j+1 else 'red' for x in range(len(data))]) | ||
time.sleep(timeTick / 100) | ||
data[j+1] = key |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import time | ||
|
||
def merge_sort(data, drawData, timeTick): | ||
merge_sort_alg(data,0,len(data)-1,drawData,timeTick) | ||
|
||
def merge_sort_alg(data, left, right, drawData, timeTick): | ||
if left < right: | ||
middle = (left+right) // 2 | ||
merge_sort_alg(data, left, middle, drawData, timeTick) | ||
merge_sort_alg(data,middle+1,right,drawData,timeTick) | ||
merge(data, left, middle, right, drawData, timeTick) | ||
|
||
def merge(data, left, middle, right, drawData,timeTick): | ||
drawData(data, getColorArray(len(data) , left, middle, right)) | ||
time.sleep(timeTick/100) | ||
|
||
leftPart = data[left:middle+1] | ||
rightPart = data[middle+1:right+1] | ||
leftIdx = rightIdx = 0 | ||
|
||
for dataIdx in range(left,right+1): | ||
if leftIdx < len(leftPart) and rightIdx < len(rightPart): | ||
if(leftPart[leftIdx] <= rightPart[rightIdx]): | ||
data[dataIdx] = leftPart[leftIdx] | ||
leftIdx += 1 | ||
else: | ||
data[dataIdx] = rightPart[rightIdx] | ||
rightIdx += 1; | ||
|
||
elif leftIdx < len(leftPart): | ||
data[dataIdx] = leftPart[leftIdx] | ||
leftIdx += 1 | ||
else: | ||
data[dataIdx] = rightPart[rightIdx] | ||
right += 1 | ||
|
||
drawData(data,["green" if x >= left and x <= right else "white" for x in range(len(data))]) | ||
time.sleep(timeTick/100) | ||
|
||
def getColorArray(length, left, middle, right): | ||
colorArray = [] | ||
|
||
for i in range(length): | ||
if i >= left and i <= right: | ||
if i >= left and i <= middle: | ||
colorArray.append("yellow") | ||
else: | ||
colorArray.append("pink") | ||
else: | ||
colorArray.append("white") | ||
|
||
return colorArray |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import time | ||
|
||
def partition(data, head, tail, drawData, timeTick): | ||
border = head | ||
pivot = data[tail] | ||
|
||
drawData(data, getColorArray(len(data), head, tail, border, border)) | ||
time.sleep(timeTick) | ||
|
||
for j in range(head, tail): | ||
if data[j] < pivot: | ||
drawData(data, getColorArray(len(data), head, tail, border, j, True)) | ||
time.sleep(timeTick/100) | ||
|
||
data[border], data[j] = data[j], data[border] | ||
border += 1 | ||
|
||
drawData(data, getColorArray(len(data), head, tail, border, j)) | ||
time.sleep(timeTick/100) | ||
|
||
|
||
#swap pivot with border value | ||
drawData(data, getColorArray(len(data), head, tail, border, tail, True)) | ||
time.sleep(timeTick/100) | ||
|
||
data[border], data[tail] = data[tail], data[border] | ||
|
||
return border | ||
|
||
def quick_sort(data, head, tail, drawData, timeTick): | ||
if head < tail: | ||
partitionIdx = partition(data, head, tail, drawData, timeTick) | ||
|
||
#LEFT PARTITION | ||
quick_sort(data, head, partitionIdx-1, drawData, timeTick) | ||
|
||
#RIGHT PARTITION | ||
quick_sort(data, partitionIdx+1, tail, drawData, timeTick) | ||
|
||
|
||
def getColorArray(dataLen, head, tail, border, currIdx, isSwaping = False): | ||
colorArray = [] | ||
for i in range(dataLen): | ||
#base coloring | ||
if i >= head and i <= tail: | ||
colorArray.append('gray') | ||
else: | ||
colorArray.append('white') | ||
|
||
if i == tail: | ||
colorArray[i] = 'blue' | ||
elif i == border: | ||
colorArray[i] = 'red' | ||
elif i == currIdx: | ||
colorArray[i] = 'yellow' | ||
|
||
if isSwaping: | ||
if i == border or i == currIdx: | ||
colorArray[i] = 'green' | ||
|
||
return colorArray |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import time | ||
|
||
def selection_sort(data,drawData,timeTick): | ||
for i in range(len(data) - 1): | ||
minIdx = i | ||
for j in range(i+1,len(data)): | ||
if data[minIdx] > data[j]: | ||
minIdx = j | ||
drawData(data,['green' if x == i or x == minIdx else 'red' for x in range(len(data))]) | ||
time.sleep(timeTick / 100) | ||
data[i] , data[minIdx] = data[minIdx], data[i] |