我用 Python 3分钟实现9种经典排序算法的可视化

640?wx_fmt=gif

导读:最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感。


不知道作者是怎么做的,但是突然很想自己实现一遍,而且用python实现特别快,花了一天的时间,完成了这个项目。主要包括希尔排序(Shell Sort)、选择排序(Selection Sort)、快速排序(Quick Sort)、归并排序(Merge Sort)等九种排序。


作者:爱笑的眼睛

来源:恋习Python(ID:sldata2017)


▲6分钟演示15种排序算法


下面具体讲解以下实现的思路,大概需要解决的问题如下:


  • 如何表示数组

  • 如何得到随机采样数组,数组有无重复数据

  • 如何实现排序算法

  • 如何把数组可视化出来



01 如何表示数组


python提供了list类型,很方便可以表示C++中的数组。标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。


对于数值运算来说这种结构显然比较浪费内存和CPU计算时间,再次就不详细论述。



02 如何得到随机采样数组,数组有无重复数据


假设我希望数组长度是100,而且我希望数组的大小也是在[0,100)内,那么如何得到100个随机的整数呢?可以用random库。


示例代码:


import random
data = list(range(100))
data = random.choices(data, k=100)
print(data)
[523345334825682878237835244469886629827784121910
2724574271752517794448186622569978656473151402141
21175688419246568023704996835416368224686016981681,
 101311246835563923446303605666382847472590893868
21]


但是以上代码有个问题,random.choices是对一个序列进行重复采样,得到的数组存在重复数据,那如果不希望存在重复数据,而是希望进行无重复采样,怎么办?


可以用random.sample函数,示例代码:


data = random.sample(data, k=100)
print(data)
[492856284462812548335438301613192356606641246868,
 77927824663809478418488215625257524388231522310
71402746333556511231225891621211142474481358688
29367716396576996682486979069106898564483477017
47826045]


这样就可以得到无重复采样数据了。



03 如何实现排序算法


算法种类较多,就不一一举例;再次就以希尔排序(Shell Sort)为例讲讲:


希尔排序的原理:希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。


希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

基础的插入法排序是两重循环,希尔排序是三重循环,最外面一重循环,控制增量gap,并逐步减少gap的值。二重循环从下标为gap的元素开始比较,依次逐个跨组处理。最后一重循环是对组内的元素进行插入法排序。


这样进行排序的优点在于每次循环,整个序列的元素都将小元素的值逐步向前移动,数值比较大的值向后移动。


示例代码:


from data import DataSeq

def ShellSort(ds):
    assert isinstance(ds, DataSeq), "Type Error"

    Length = ds.length
    D = Length//2
    while D>0:
        i=0
        while i<Length:
            tmp = ds.data[i]

            j=i
            while j>=1 and ds.data[j-D]>tmp:
                ds.SetVal(j, ds.data[j-D])
                j-=D
            ds.SetVal(j, tmp)

            i+=D
        D//=2

if __name__ == "__main__":
    ds=DataSeq(64)
    ds.Visualize()
    ds.StartTimer()
    ShellSort(ds)
    ds.StopTimer()
    ds.SetTimeInterval(0)
    ds.Visualize()



04 如何把数组可视化出来


有了随机数组初始化方法,再实现好排序函数,我们还差一步,就是把排序函数中每次移动数组后将数组可视化并输出。


对数组进行可视化,很容易想到python的可视化工具matplotlib!但是在项目中我并没有用matplotlib,而是用了numpy+opencv


为什么不用matplotlib?


因为在排序过程中,每次修改数组,都希望能够实时修改图片并输出,matplotlib确实很方便,但是matplotlib的效率实在是不高,而且每次修改数组前后的两幅图片其实是差不多的。如果用matplotlib,每次都是要重新绘制图片,非常耗时!!!


所以考虑自己生成图片,在每次修改数组后,只将图片中改动的那两列进行修改即可!这样就比用matplotlib每次重新绘制图片效率高得多!


数组中主要有两种操作,一种是对某个idx赋值,一种是交换某两个idx的值。


示例代码:


class DataSeq:
    WHITE = (255,255,255)
    RED = (0,0,255)
    BLACK = (0,0,0)
    YELLOW = (0,127,255)
    def __init__(self, Length, time_interval=1, sort_title="Figure", repeatition=False):
        pass
    def Getfigure(self):
        _bar_width = 5
        figure = np.full((self.length*_bar_width,self.length*_bar_width,3), 255,dtype=np.uint8)
        for i in range(self.length):
            val = self.data[i]
            figure[-1-val*_bar_width:, i*_bar_width:i*_bar_width+_bar_width] = self.GetColor(val, self.length)
        self._bar_width = _bar_width
        self.figure = figure
    def _set_figure(self, idx, val):
        min_col = idx*self._bar_width
        max_col = min_col+self._bar_width
        min_row = -1-val*self._bar_width
        self.figure[ : , min_col:max_col] = self.WHITE
        self.figure[ min_row: , min_col:max_col] = self.GetColor(val, self.length)
    def SetVal(self, idx, val):
        self.data[idx] = val
        self._set_figure(idx, val)

        self.Visualize((idx,))

    def Swap(self, idx1, idx2):
        self.data[idx1], self.data[idx2] = self.data[idx2], self.data[idx1]
        self._set_figure(idx1, self.data[idx1])
        self._set_figure(idx2, self.data[idx2])

        self.Visualize((idx1, idx2))


附上一张效果图:


640?wx_fmt=jpeg


附上源码链接:

https://github.com/ZQPei/Sorting_Visualization

(觉得不错,记得帮忙点个star哦)


640?


据统计,99%的大咖都完成了这个神操作


640?wx_fmt=png


更多精彩


在公众号后台对话框输入以下关键词

查看更多优质内容!


PPT | 报告 | 读书 | 书单 | 干货 

大数据 | 揭秘 | Python | 可视化

人工智能 | 机器学习 | 深度学习 | 神经网络

AI | 1024 | 段子 | 区块链 | 数学


猜你想看




Q: 你都在用哪些排序算法

欢迎留言与大家分享

觉得不错,请把这篇文章分享给你的朋友

转载 / 投稿请联系:baiyu@hzbook.com

更多精彩,请在后台点击“历史文章”查看

640?wx_fmt=jpeg

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在中,可以使用各排序算法对数据进行排序,并通过可视化来展示排序的过程。以下是三常见的排序算法可视化实现方法: 1. 选择排序:选择排序是一简单直观的排序算法。它的工作原理是从未排序序列中找到最小元素,并将其放置到已排序序列的末尾。可以通过绘制柱状图来展示选择排序的过程,其中每个柱子代表一个元素,柱子的高度表示该元素的值。在每一轮选择中,最小的元素会被放置在已排序序列的末尾。可以通过不断更新柱子的颜色来表示已排序的部分。 2. 归并排序:归并排序利用分治法的思想,先递归地分解数组,然后再合并数组。可以通过绘制折线图来展示归并排序的过程,其中每个点代表一个元素,点的纵坐标表示该元素的值。在每一次合并的过程中,比较两个有序数组的元素,并将较小的元素放置在结果数组中。可以通过连接点和画线来表示合并的过程。 3. 冒泡排序:冒泡排序的原理是通过重复地比较相邻的元素,如果前者比后者大,则交换它们。可以通过绘制柱状图来展示冒泡排序的过程,其中每个柱子代表一个元素,柱子的高度表示该元素的值。在每一轮比较中,较大的元素会像气泡一样浮到数组的顶部。可以通过不断更新柱子的颜色来表示已排序的部分。 这些排序算法可视化实现可以帮助我们更好地理解它们的原理和过程。可以使用Python可视化库(如matplotlib)来实现排序算法可视化。通过绘制不同的图形来展示排序的过程,可以使我们更直观地观察到元素的比较和交换。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [python排序算法可视化](https://blog.csdn.net/weixin_42788078/article/details/88607161)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值