各类排序动态可视化(OpenCV)

参考修改
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scc_hy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值