用Python动态展示排序算法

文章目录

    • 选择冒泡
    • 插入排序
    • 归并排序
    • 希尔排序

经常看到这种算法可视化的图片,但往往做不到和画图的人心灵相通,所以想自己画一下,本文主要实现归并排序和希尔排序,如果想实现其他算法可参考这篇

C语言实现各种排序算法[选择,冒泡,插入,归并,希尔,快排,堆排序,计数]

选择冒泡

这两种排序方案简单到很难说是什么算法,其中选择排序通过遍历一次数组,选出其中最大(小)的值放在新数组的第一位,再从剩下的数里选出最大(小)的,放到第二位,依次类推;冒泡排序则是通过重复走访要排序的数组,比较相邻元素,如果顺序不符合要求则交换位置,直到不需要交换为止。

选择排序冒泡排序
在这里插入图片描述在这里插入图片描述

二者的核心代码分别为:

#x为待排序列表,N=len(x)
#选择排序
for i in range(N):iMax = ifor j in range(i, N):if(x[j]>x[iMax]):iMax = jx[iMax],x[i] = x[i],x[iMax]#冒泡排序
tempN = N-1
for i in range(tempN):for j in range(0, tempN-i):if(x[j]>x[j+1]):x[j],x[j+1] = x[j+1],x[j]

下面给出选择排序的绘图代码,其他的所有排序算法,其实只需改变核心部分。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation start,end,N = 10,100,9
x = np.random.randint(start, end, size=N)
Index = np.arange(N)
xs = []
nowIndex = []for i in range(N):iMax = ifor j in range(i, N):xs.append(x*1)      #存储当前顺序,用于绘图nowIndex.append([i,j,iMax]) #存储当前的i,j,max位置,用于绘图if(x[j]>x[iMax]):iMax = jxs.append(x*1)nowIndex.append([i,j,iMax])x[iMax],x[i] = x[i],x[iMax]fig, ax = plt.subplots()
colors = np.repeat('g',N)
colors[0] = 'b'
bar = ax.bar(Index,x,color=colors)def animate(n):data = xs[n]colors = np.repeat('gray',N)colors[nowIndex[n]] = 'b','g','r'ax.clear()bar = ax.bar(Index, data, color=colors)return barani = animation.FuncAnimation(fig, animate, range(len(xs)), interval=500, repeat=False, blit=True)
plt.show()
ani.save("sort.gif")

插入排序

插入排序的基本思路是将数组分为前后两个部分,前面有序,后面无序。逐个扫描无序数组,将每次扫描的数插入到有序数组中,从而有序数组越来越长,无序数组越来越短,直到整个数组都是有序的。

核心代码为

for i in range(1,N):j = i-1temp = x[i]while(x[i]<x[j] and j>=0):x[j+1] = x[j]j -= 1x[j+1] = temp

由于在这段代码中, x i x_i xi被取出放在旁边,所以其动态图中大部分时间会缺失一个值,在图中将其置于最右侧,其动态过程如图所示,蓝色表示抽出来准备插进去的那根bar

在这里插入图片描述

归并排序

排序算法到这里才算有点意思,归并排序是算法导论中介绍分治概念时提到的,基本思路是将数组拆分成子数组,然后令子数组有序,再令数组之间有序,从而整个数组有序。

算法步骤 \textbf{算法步骤} 算法步骤

设数组有 n n n个元素, { a 0 , a 1 , … , a n } \{a_0,a_1,\ldots,a_n\} {a0,a1,,an}

  1. 如果数组元素大于2,则将数组分成左数组和右数组,如果数组等于2,则将数组转成有序数组
  2. 对左数组和右数组执行1操作。
  3. 合并左数组和右数组。

可以发现,对长度为 n n n的数组,需要 log ⁡ 2 n \log_2n log2n次的拆分,每个拆分层级都有 O ( n ) O(n) O(n)的时间复杂度和 O ( n ) O(n) O(n)的空间复杂度,所以其时间复杂度和空间复杂度分别为 O ( n log ⁡ 2 n ) 和 O ( n ) O(n\log_2n)和O(n) O(nlog2n)O(n)

其核心算法为

def Merge(X, Y):nL,nR = len(X), len(Y)iterL,iterR = 0,0xNew = []for _ in range(nL+nR):if(iterL==nL): return xNew + Y[iterR:]if(iterR==nR): return xNew + X[iterL:]if(X[iterL]<Y[iterR]):xNew.append(X[iterL])iterL += 1else:xNew.append(Y[iterR])iterR += 1return xNewdef MergeSort(x):if len(x)==1:return xif len(x)==2:return x if x[0]<x[1] else [x[1],x[0]]nL = len(x)//2return Merge(MergeSort(x[:nL]),MergeSort(x[nL:]))

当然这么写效率是非常低的,如果像高效还是得用指针,但我都已经用Python了,所以就不去想效率的问题,问题的关键是这种带有返回值的递归程序根本没法画图啊。。。所以还是改成指针的写法

def Merge(X, nL):nR = len(X)-nLXL,XR = X[:nL]*1,X[nL:]*1iterL,iterR = 0,0for i in range(nL+nR):if(iterL==nL): breakif(iterR==nR): X[i:] = XL[iterL:]returnif(XL[iterL]<XR[iterR]):X[i] = XL[iterL]iterL += 1else:X[i] = XR[iterR]iterR += 1def MergeSort(X):if len(X)<2:returnnL = len(X)//2MergeSort(X[:nL])MergeSort(X[nL:])Merge(X,nL)

这个图。。怎么说呢,因为在【Merge】过程中,有很多bar被掩盖掉了,所以可能只有画图的人能看懂吧。。。

在这里插入图片描述

希尔排序

据说是第一个突破 O ( n 2 ) O(n^2) O(n2)的排序算法,又称为缩小增量排序,本质上也是一种分治方案。

在归并排序中,先将长度为n的数组划分为nL和nR两部分,然后继续划分,直到每个数组的长度不大于2,再对每个不大于2的数组进行排序。这样,每个子数组内部有序而整体无序,然后将有序的数组进行回溯重组,直到重新变成长度为n的数组为止。

希尔排序反其道而行之,在将数组划分为nL和nR后,对nL和nR进行按位排序,使得nL和nR内部无序,但整体有序。然后再将数组进行细分,当数组长度变成1的时候,内部也就谈不上无序了,而所有长度为1的数组整体有序,也就是说有这些子数组所组成的数组是有序的。

算法步骤 \textbf{算法步骤} 算法步骤

设数组有 n n n个元素, { a 0 , a 1 , … , a n } \{a_0,a_1,\ldots,a_n\} {a0,a1,,an}

  1. 如果数组元素大于2,则将数组分成左数组和右数组,并对左数组和右数组的元素进行一对一地排序。
  2. 对每一个数组进行细分,然后将每个子数组进行一对一排序。
def ShellSort(arr):n = len(arr)nSub = n//2while nSub>0:for i in range(nSub,n):temp = arr[i]j = i-nSubwhile j>=0 and temp<arr[j]:arr[j+nSub] = arr[j]j -= nSubarr[j+nSub] = tempnSub //= 2

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777879.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

《雾锁王国》服务器怎么搭建,阿里云一键部署雾锁王国新手教程

上次讲了怎么搭建幻兽帕鲁服务器&#xff0c;今天讲讲如何搭建雾锁王国服务器&#xff0c;其实方法也非常简单&#xff0c;跟幻兽帕鲁一样&#xff0c;都是可以通过一键部署的方式来搭建的。 下面将会讲两种搭建《雾锁王国》服务器的方式&#xff0c;一种是你没有买过服务器&a…

leetcode:51.N皇后

起初会想到暴力&#xff0c;但是N不确定&#xff0c;所以不确定for的嵌套层数&#xff0c;所以我们采用回溯算法。 树形结构&#xff1a; 1.树的深度是第depth层 2.树的宽度是对每一行进行遍历 代码实现&#xff1a; 1.result是三维数组&#xff0c;一个棋盘是二维&#x…

电商小程序06用户审核

目录 1 创建自定义应用2 显示待办数量3 创建审核页面4 开发审核功能5 搭建布局6 最终效果总结 上一篇我们讲解了用户注册的功能&#xff0c;用户注册之后状态是待审核&#xff0c;需要管理员进行审核。通常给管理员提供一套PC端的软件进行相关的操作&#xff0c;在低代码中&…

Java强训day18(选择题编程题)

选择题 编程题 题目1 import java.util.Scanner;public class Main { public static void main(String[] args) {//1 |1 //1 |1//1 1 |2//1 1 1 |3//1 1 1 1 1 |5Scanner sc new Scanner(System.in);int n sc.nextInt();//从出生后第3个月起每个月都生一只兔子//一月的时…

FRP内网穿透如何避免SSH暴力破解(二)——指定地区允许访问

背景 上篇文章说到&#xff0c;出现了试图反复通过FRP的隧道&#xff0c;建立外网端口到内网服务器TCP链路的机器人&#xff0c;同时试图暴力破解ssh。这些连接造成了流量的浪费和不必要的通信开销。考虑到服务器使用者主要分布在A、B、C地区和国家&#xff0c;我打算对上一篇…

政安晨:示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(二){两篇文章讲清楚}

这一篇与上一篇是兄弟篇&#xff0c;意在通过两篇文章讲清楚深度学习中神经网络的数学基础&#xff0c;第一次看到这篇文章的小伙伴可以从上一篇文章看起&#xff08;包括搭建环境等等都在上一篇&#xff09;&#xff0c;上一篇链接如下&#xff1a; 政安晨&#xff1a;示例演…

【Linux】模块出入点与模块信息

&#x1f525;博客主页&#xff1a;PannLZ &#x1f38b;系列专栏&#xff1a;《Linux系统之路》 &#x1f94a;不要让自己再留有遗憾&#xff0c;加油吧&#xff01; 文章目录 1模块的入点和出点2模块信息 1模块的入点和出点 内核驱动程序都有入点和出点&#xff1a;前者对应…

《CSS 简易速速上手小册》第1章:CSS 基础入门(2024 最新版)

文章目录 1.1 CSS 语法和选择器&#xff1a;挑选你的画笔1.1.1 基础知识1.1.2 重点案例&#xff1a;创建一个响应式导航菜单1.1.3 拓展案例 1&#xff1a;为特定链接添加图标1.1.4 拓展案例 2&#xff1a;创建一个简单的问答折叠面板 1.2 盒模型的基础&#xff1a;构建你的乐高…

腾讯云4核8G服务器最大能承载多少用户在线?12M带宽

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

[架构之路-275]:五张图向你展现软件开发不仅仅是编码,而是一个庞大的系统工程

目录 一、软件开发是组织架构的一部分&#xff0c;是为业务服务的 二、软件开发是一个系统工程&#xff0c;需要组织各种组织内的资源 三、目标软件是一个复杂的系统 四、软件开发过程本身是一个系统工程 五、目标软件的测试验证是一个系统工程 一、软件开发是组织架构的一…

lv14 led驱动设备树版本 13

led驱动代码中无法给其他开发板重用&#xff0c;编程依据不清晰&#xff0c;如下&#xff0c;修改后尽量在代码中不直接修改寄存器。 把编程依据写到设备树中 一、起源 减少垃圾代码 减轻驱动开发工作量 驱动代码和设备信息分离 参考Open Fireware设计 用来记录硬件平台中…

数据结构-->线性表-->单链表

链表的定义 链表&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 与顺序表不同的是&#xff0c;链表里的每节都是独立申请下来的空间&#xff0c;我们称之为“节点、结点”。 节点的组成主要由…

机器翻译后的美赛论文怎么润色

美赛论文的语言表达一直是组委会看重的点&#xff0c;清晰的思路和地道的语言在评审中是重要的加分项。 今天我们就来讲讲美赛论文的语言问题。 我相信有相当一部分队伍在打美赛的时候&#xff0c;出于效率的考量&#xff0c;都会选择先写中文论文&#xff0c;再机翻成英文。 …

ChatGPT4 教你如何完成SQL的实践应用

对数据库的各项应用与操作都离不开SQL来对数据进行增删改查。 例如 &#xff1a; 有一张某公司职员信息表如下&#xff1a; 需求1&#xff1a;在公司职员信息表中&#xff0c;请统计各部门&#xff0c;各岗位下的员工人数。 如果这个SQL语句不会写或者不知道怎么操作可以交给…

Linux运行级别 | 管理Linux服务

Linux运行级别 级别&#xff1a; 0关机1单用户2多用户但是不运行nfs网路文件系统3默认的运行级别&#xff0c;给一个黑的屏幕&#xff0c;只能敲命令4未使用5默认的运行级别&#xff0c;图形界面6重启切换运行级别&#xff1a; init x管理Linux服务 systemctl命令&#xf…

【北邮鲁鹏老师计算机视觉课程笔记】02 filter

1 图像的类型 二进制图像&#xff1a; 灰度图像&#xff1a; 彩色图像&#xff1a; 2 任务&#xff1a;图像去噪 噪声点让我们看得难受是因为噪声点与周边像素差别很大 3 均值 滤波核 卷积核 4 卷积操作 对应相乘再累加起来 卷积核记录了权值&#xff0c;把权值套到要卷积…

vivo发布2023 年度科技创新;阿里全新AI代理,可模拟人类操作手机

vivo 发布 2023 年度十大产品技术创新 近日&#xff0c;vivo 发布了「2023 年度科技创新」十大产品技术创新榜单&#xff0c;并将这些技术分为了 4 个板块。 「四大蓝科技」为 vivo 在去年推出的全新技术品牌&#xff0c;涵盖蓝晶芯片技术栈、蓝海续航系统、蓝心大模型、蓝河操…

基于springboot会员制医疗预约服务管理信息系统源码和论文

会员制医疗预约服务管理信息系统是针对会员制医疗预约服务管理方面必不可少的一个部分。在会员制医疗预约服务管理的整个过程中&#xff0c;会员制医疗预约服务管理系统担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类的管理系统也在不断改进。本课题所设计…

sqlmap 使用笔记(kali环境)

sqlmap使用 kali环境 -u或–url 直接扫描单个路径 //如果需要登录要有cookie sqlmap -u "http://10.0.0.6:8080/vulnerabilities/sqli/?id1" --cookie"PHPSESSIDisgvp2rv4uts46jbkb9bouq6ir; securitylow"-m 文件中保存多个url&#xff0c;工具会依次扫…

93 log4j-slf4j-impl 搭配上 log4j-to-slf4j 导致的 StackOverflow

前言 呵呵 最近想要 做一个 mongo 低版本的客户端读取高版本的服务端传递过来的数据造成的一个错误的时候, 出现了这样的问题 引入了 mongo-java-driver 之后, 使用相关 api 的时候会触发 com.mongo.internal.connection.BaseCluser 的初始化, 其依赖的 Loggers 间接的依赖…