参考修改
ZQPei的GitHub Sorting_Visualization 项目链接
修改后笔者GitHub项目链接
以下仅列举出对原脚本有修改的排序算法
windows 环境下
0-选择排序(SelectionSort)
# 加载包
import sys
import os
root_path = 'D:/Python_data/gihub_project/sorting_va_20190620' #'E:/Python Data/Sorting_v'
sys.path.append(root_path)
from my_data import get_data
from my_data import get_figure2draw
def SelectionSort(ds):
assert isinstance(ds, get_figure2draw), "Type Error"
Length = ds.length
for i in range(Length):
swap_bool = True
while swap_bool and i < Length - 1: # 优化: 交换一次就停止
for j in range(i, Length):
if ds.data[j] < ds.data[i]:
ds.swap(i,j)
swap_bool = False
if __name__ == "__main__":
data = get_data(100)
ds = get_figure2draw(data, sort_title = 'SelectionSort')
ds.Visualize() # 画出底图
SelectionSort(ds)
ds.set_time_interval(0)
ds.Visualize() # 画出排序结束后的图
try:
sys.path.remove(root_path)
except:
pass
优化前后时间排序时间对比
1- 桶排序(BucketSort)
# 加载包
import sys
import os
import copy
root_path = 'E:/Python Data/Sorting_v'
sys.path.append(root_path)
from my_data import get_data
from my_data import get_figure2draw
def BucketSort(ds):
"""
桶排序只适用于整数排序,且最大元素不能比数值元素大太多
空桶[ 待排数组[ 0 ] ] = 待排数组[ 0 ]
"""
assert isinstance(ds, get_figure2draw), "Type Error"
assert isinstance(ds.data[0], int), "Type Error"
Lengh = ds.length
dt = ds.data
bucket = [0 for _ in range(max(dt) + 1)]
for i in range(Lengh):
bucket[ dt[i] ] = dt[i]
j = 0
for i in range(Lengh):
tmp = bucket[i]
while tmp != 'stp': # 有值位置才排序
ds.set_val(j , tmp)
tmp = 'stp'
j += 1
if __name__ == "__main__":
data = get_data(64)
ds = get_figure2draw(data, sort_title = 'BucketSort')
ds.Visualize() # 画出底图
BucketSort(ds)
ds.set_time_interval(0)
ds.Visualize() # 画出排序结束后的图
try:
sys.path.remove(root_path)
except:
pass
2- 圈排序(CycleSort)
import sys
import os
root_path = 'E:/Python Data/Sorting_v'
sys.path.append(root_path)
from my_data import get_data
from my_data import get_figure2draw
def CycleSort(ds):
"""
环排序只适用于整数排序,且数正好范围在[0,N-1]内,且只有少量重复元素,不稳定
"""
assert isinstance(ds, get_figure2draw), "Type Error"
assert isinstance(ds.data[0], int), "Type Error"
Length = ds.length
dt = ds.data
# 重复元素的列表
repeatIdxs = []
for i in range(Length):
currIdx = i
# 查找当前值应该所在的索引
shouldIdx = sum([1 if dt[currIdx] > v else 0 for v in dt ])
# cycle 跑圈 (忽视重复值)
while currIdx != shouldIdx and dt[currIdx] != dt[shouldIdx]: # 当前位置不是应该所在的位置的时候
ds.swap(currIdx, shouldIdx) # 交换 currIdx, shouldIdx 的值
shouldIdx = sum([1 if dt[currIdx] > v else 0 for v in dt ])
# 可能包含重复的值记录
if dt[currIdx] == dt[shouldIdx] and currIdx != shouldIdx:
repeatIdxs.append([currIdx, shouldIdx])
# 重复元素插值
for rep in repeatIdxs:
if dt[rep[0]] == dt[rep[1]]:
ds.set_val(rep[0], dt[max(rep[0] - 1, 0)])
if __name__ == "__main__":
# data = get_data(64)
data = [51, 8, 46, 18, 40, 20, 14, 33, 5, 10, 62, 48, 53
, 56, 0, 60, 6, 42, 39, 57, 25, 54, 59, 24, 19, 55, 32, 30
, 58, 38, 29, 50, 49, 22, 44, 3, 7, 28, 16, 26
, 41, 52, 4, 23, 35, 31, 36, 43, 61, 17, 37, 13
, 45, 15, 9, 34, 47, 12, 27, 21, 11, 63, 2, 1, 2, 13, 2, 8]
ds = get_figure2draw(data, sort_title = 'CycleSort')
ds.Visualize() # 画出底图
CycleSort(ds)
ds.set_time_interval(0)
ds.Visualize() # 画出排序结束后的图
try:
sys.path.remove(root_path)
except:
pass
3- 堆排序(HeapSort)
# 加载包
import sys
import os
root_path = 'E:/Python Data/Sorting_v'
sys.path.append(root_path)
from my_data import get_data
from my_data import get_figure2draw
def big_endian(ds, root, end):
"""
将堆的末端子节点作调整,使得子节点永远小于父节点
:param: ds get_figure2draw
:param: root int 开始(list index)
:param: end int 结束(list index)
"""
arr = ds.data
child = root * 2 + 1 # 左子节点
while child <= end:
if child + 1 <= end and arr[child] < arr[child + 1] :
# 判断右child是否存在,如果存在则和另外一个同级节点进行比较
child += 1
if arr[root] < arr[child]:
ds.swap(root, child)
## 下钻到下层
root = child
child = root * 2 + 1
else:
break
def HeapSort(ds):
"""
堆排序
"""
Length = ds.length - 1
first = Length // 2
for root in range(first, -1, -1):
# 建堆
big_endian(ds, root, Length)
for end in range(Length, 0, -1):
# 堆顶是最大的值,放到最末尾,长度-1后继续建堆
ds.swap(0, end)
big_endian(ds, 0, end - 1)
if __name__ == "__main__":
data = get_data(64)
ds = get_figure2draw(data, sort_title = 'HeapSort')
ds.Visualize() # 画出底图
HeapSort(ds)
ds.set_time_interval(0)
ds.Visualize() # 画出排序结束后的图
try:
sys.path.remove(root_path)
except:
pass