排序算法可视化,包含了两个部分,一个是排序算法,一个是可视化。
排序算法本身就是个大难题,包括冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序,基数排序,堆排序,计数排序,桶排序,可惜我只会冒泡排序,呵呵,不过希望能够硬着头皮学习一下。算法还包括空间复杂度,时间复杂度,稳定性等等。
可视化方案也有多种,matplotlib的,pygame的,pyqt的,想来想去还是matplotlib最省事,不过尝试半天也很费劲,matplotlib也提供了不同的方式,先尝试着完成一种,另一种还在慢慢琢磨,并尝试着写的优雅些。
既然是写代码,当然首先得阅读代码,再次是写好点,比如封装点对象,增加标准的计算时间函数,把代码优雅的写好一点,把注释尽量写完整一些等等。
优化是个过程,得慢慢来。
代码示例
代码语言:javascript复制import random
import copy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def init_sortdata(datarage=10,datanum=10):
data = list(range(datarage))
data = random.sample(data, k=datanum)
return data
#计算时间函数
def print_run_time(func):
def wrapper(*args, **kw):
start_time = time.time() # 程序开始时间
ret=func(*args, **kw) # 将被装饰函数的返回值接收
end_time = time.time() # 程序结束时间
total_time = int(1000*(end_time - start_time)) #程序执行时间,毫秒计
print('{}排序算法共计执行{}豪秒,开始时间为{},结束时间为{}'.format(func.__name__,total_time,start_time,end_time))
return ret # 返回被装饰函数的返回值
return wrapper
class SortClass:
def __init__(self,collection):
self.collection=collection
def swapAndDraw(self,tempbar, x1, x2):
#tempbar 为 <BarContainer object of X artists>
#tempbar[x1] 为 Rectangle(xy=(9.6, 0), width=0.8, height=98, angle=0) 对象
temp1height = tempbar[x1].get_height() #获取待交换图像x1的高度,写入临时变量
tempbar[x1].set_height(tempbar[x2].get_height()) #将x1的高度置为x2的高度
tempbar[x2].set_height(temp1height) #将x2的高度置为x1的高度
tempbar[x2].set_fc("red") #将要交换的x2置为红色标志
plt.draw() #绘制图形
plt.pause(0.1) #为体现动画,设置延迟时间为0.1秒
tempbar[x2].set_fc("green") #再将要交换的x2重置为绿色标志
@print_run_time
def bubble_sort(self):
#冒泡排序,数据来自类的初始化,为了不改变源list数据,采用深拷贝方式
dataset = copy.deepcopy(self.collection)
stepdata=[]
length = len(dataset) #list长度
runtimes=0 #交换次数
looptimes=0 #循环次数
print('原始数据=',dataset) #记录原始数据
plt.figure('bubble_sort')
plt.title('bubble_sort')
plt.xticks(range(0,length), rotation=45) #进行X轴设置
tempbar = plt.bar(range(length), dataset, fc="green") #初始化元数据
for i in range(length - 1):
print(' 第{}轮外轮,开始数据={}'.format(i, dataset))
swapped = False
for j in range(length - 1 - i):
if dataset[j] > dataset[j 1]: #相邻元素间交叉判断
swapped = True
runtimes=runtimes 1 #记录交换次数
dataset[j], dataset[j 1] = dataset[j 1], dataset[j] #数据交换
stepdata.append(dataset.copy()) #
self.swapAndDraw(tempbar, j, j 1) #绘制动画图
looptimes=looptimes 1 #记录循环次数
print(' 第{}轮内轮,中间数据={}'.format(j, dataset)) #记录内轮中间数据
if not swapped:
break
print(' 第{}轮外轮,结束数据={}'.format(i,dataset)) #记录外轮中间数据
print('最终数据=', dataset) #记录最终数据
plt.ioff()
return looptimes,runtimes,dataset,stepdata
if __name__ == "__main__":
import time
orgdata=init_sortdata(100,10)
asort=SortClass(orgdata)
looptimes,runtime,sortdata,stepdata=asort.bubble_sort()
print('排序前的数据为{}'.format(orgdata))
print('排序后的数据为{}'.format(sortdata))
print('循环次数={}'.format(looptimes))
print('交换次数={}'.format(runtime))
print('stepdata={}'.format(stepdata))