在Python中使用 Tkinter 可视化合并排序
先决条件: Python GUI – tkinter
在本文中,我们将创建一个 GUI 应用程序,帮助我们在Python中使用 Tkinter 可视化合并排序算法。
归并排序是一种流行的排序算法。它的时间复杂度为 N(logN),比冒泡排序或选择排序等其他排序算法要快。通过创建这个应用程序,我们将能够可视化归并排序的工作原理。合并排序遵循分而治之的范式。它涉及三个步骤
- 划分:将问题划分为类似小问题的子集
- 征服:递归解决子问题。
- 合并:将子问题的解合二为一,找到原始答案
在归并排序中,数组被分成几乎相等的两半,这个过程一直持续到只有两个数组元素需要排序。然后我们合并它们,使得结果数组将是一个排序数组。它帮助我们理解或可视化合并排序如何使用分而治之的技术。
入门
首先,为项目导入所需的模块。导入 NumPy 以生成数组并对其进行洗牌。导入 Tkinter 显然是为了创建 GUI 界面。最后,导入时间以减慢排序过程,这对于可视化至关重要。
方法
- 定义了一个函数show(),将数组显示为条形图。它需要三个参数 n、数据和颜色。 N 是数组“数据”的长度。颜色是要在画布上绘制的每个条的颜色数组。
- Shuffle() 是一个不言自明的函数,它只是打乱数组并在调用函数时显示它。
- 然后是真正的mergesort() 实现函数。
- Start()函数将触发合并排序函数,然后排序算法将启动。
- win,创建一个 Tkinter 对象。
- 然后创建一个画布和两个按钮,分配按下按钮时将触发的相应功能。
颜色代码:
合并选定的两个元素时使用蓝色显示。如果第一个子数组的元素大于最后一个子数组的元素,则使用红色。然后,一旦交换了两个元素,它将显示为绿色。当数组最终排序时,所有条形的最终颜色将为紫色。
代码:
Python3
# importing all necessary modules
from tkinter import *
from tkinter import ttk
import numpy as np
import time
def show(n: int, data: list, colours: list):
# n is length of the array data
# data is the array itself
# colours is an array of colors
canvas.delete('all')
# width variable is the width of each bar
width = 1560/(3*n-1)
# gap is the spacing between the bars
gap = width/2
for i in range(n):
# this function will display an array of "bar"
canvas.create_rectangle(7+i*width+i*gap, 0, 7 +
(i+1)*width+i*gap, data[i],
fill=colours[i])
# this function will help us to see every step
# of the sorting algorithm
# the purpose of this function is to update the screen
# in runtime
win.update_idletasks()
def shuffle():
np.random.shuffle(arr)
show(N, arr, color)
def mergesort(arr, left, right):
if left < right:
m = (left+right)//2
mergesort(arr, left, m)
mergesort(arr, m+1, right)
j = m+1
if arr[m] <= arr[m+1]:
return
while left <= m and j <= right:
show(N, arr, ['blue' if x == left or x ==
j else 'grey' for x in range(N)])
time.sleep(1/speed)
if arr[left] <= arr[j]:
left += 1
else:
show(N, arr, ['red' if x == left or x ==
j else 'grey' for x in range(N)])
# array of colours where only the focused bars
# are displayed red since left >arr[j]
time.sleep(1/speed)
temp = arr[j]
# storing the smaller element in temp variable
i = j
while i != left:
arr[i] = arr[i-1]
show(N, arr, ['red' if x == i or x ==
j else 'grey' for x in range(N)])
time.sleep(1/speed)
i -= 1
# this while loop will shift all the elements one step
# to right to make the place empty for the temp variable
# upon reaching the desired location i.e. left, the
# temp value will be inserted into that location.
# this process is much like insertion sort
arr[left] = temp
show(N, arr, ['green' if x == left or x ==
j else 'grey' for x in range(N)])
time.sleep(1/speed)
left += 1
m += 1
j += 1
# this function call the mergesort function which will
# start the animation.
def start():
mergesort(arr, 0, N-1)
show(N, arr, ['purple' for _ in range(N)])
win = Tk()
N = 50 # length of the array
speed = 100 # how fast the array will be sorted
# creating the array using linspace function
# from numpy
arr = np.linspace(10, 390, N, dtype=np.uint16)
color = ['grey' for _ in range(N)]
ttk.Label(win, text='Merge Sort visualizer').pack()
canvas = Canvas(win, width=800, height=400, bg='white')
canvas.pack()
ttk.Button(win, text='Start sorting', command=start).pack(
side='right', padx=5, pady=5)
ttk.Button(win, text='Shuffle array', command=shuffle).pack(side='right')
shuffle()
show(N, arr, color)
win.mainloop()
输出: