Python算法100例-1.8 冒泡排序

news2024/11/28 20:58:25

完整源代码项目地址,关注博主私信’源代码’后可获取

  • 1.问题描述
  • 2.问题分析
  • 3.算法设计
  • 4.完整的程序
  • 5.问题拓展

1.问题描述

对N个整数(数据由键盘输入)进行升序排列。

2.问题分析

对于N个类型相同的数,我们可利用数组进行存储。冒泡排序是利用两个相邻元素之间进行比较交换的过程将一个无序表变成有序表。

冒泡排序的思想是:首先,从表头开始往后扫描数组,在扫描过程中逐对比较相邻两个元素的大小。若相邻两个元素中,前面的元素大于后面的元素,则将它们互换,称之为消去了一个逆序。在扫描过程中,不断地将两相邻元素中的大者往后移动,最后就将数组中的最大者换到了表的最后,这正是数组中最大元素应有的位置。然后,在剩下的数组元素中(n-1个元素)重复上面的过程,将次小元素放到倒数第2个位置。不断重复上述过程,直到剩下的数组元素为0为止,此时的数组就变为了有序。假设数组元素的个数为n,在最坏的情况下需要的比较总次数为:((n-1)+(n-2)+…+2+1)=n(n-1)/2。

3.算法设计

冒泡排序的过程我们可以用示意图简单地表示,如图所示。从整个排序过程中寻找规律,可知n个元素只需比较n-1次即可。假设一个数组中有7个元素,现在对这7个元素进行排序,只需比较6次即可得到所要的有序序列。示意图中最后加粗的数字即为经过一次交换位置固定的数字。

在这里插入图片描述

数组名用a表示,数组下标用j表示,则数组中相邻两个元素的下标可表示为a[j]、a[j+1]或a[j-1]、a[j]。在利用数组解决问题时需要注意数组下标不要越界,假如定义一个整形数组int a[n],则数组元素下标的取值范围是0~n-1,下标小于0或者大于n-1都视为下标越界。如果相邻元素采用a[j]、a[j+1]表示,则下标取值范围是0~n-2,如果采用a[j-1]、a[j]表示,下标取值范围则是1~n-1,所以读者在进行编程时一定要注数组下标越界的问题。

数组元素互换也是经常遇到的一类题型,一般这种情况下我们需要借助一个中间变量才可以完成,对于许多初学者来说经常犯的一个错误是对两个元素直接相互赋值,而不借助中间变量。我们先来看一个生活中的例子,在蓝墨水瓶中装有蓝墨水,红墨水瓶中装有红墨水,现在我们要把蓝墨水放到红墨水瓶中,红墨水放到蓝墨水瓶中。做法是先找一个白色空瓶(作用相当于程序中的中间变量),首先将蓝墨水倒入白色空瓶(t=a[i]或t=a[i+1]),接着将红墨水倒入蓝墨水瓶(a[i]=a[i+1]或a[i+1]=a[i]),最后将白瓶中的蓝墨水倒入红墨水瓶(a[i+1]=t或a[i]=t),经过这三步就完成了红墨水与蓝墨水的互换。如果不借助白色空瓶,直接把蓝墨水倒入红墨水瓶或把红墨水倒入蓝墨水瓶,这样必将破坏原来所存储的内容。第一次的交换过程可以用简单的程序段进行表示,代码如下:

for j in range(0, n-1):
    if a[j] > a[j+1]:
            t = a[j]                                    # 使用变量t暂存
            a[j] = a[j+1]
            a[j+1] = t

第二次的交换过程(最后一个元素经过第一轮比较已经确定,不需要再次进行比较)可表示为:

for j in range(0, n-2):
    if a[j] > a[j+1]:
        t = a[j]                                    # 使用变量t暂存
        a[j] = a[j + 1]
        a[j + 1] = t

第三次的交换过程(最后两个元素已经确定,不需要再次进行比较)可表示为:

for j in range(0, n-3):
    if a[j] > a[j+1]:
        t = a[j]                                    # 使用变量t暂存
        a[j] = a[j + 1]
        a[j + 1] = t

由上面的程序段可以发现,第一次比较的判定条件为j<n-1,第二次为j<n-2,第三次为j<n-3,以此类推,第i次的循环判定条件必为j<n-i。在编程过程中我们可以用两层循环来控制,第一层循环控制交换的轮数,第二层循环控制每轮需要交换的次数。

4.完整的程序

程序流程图如图所示。

在这里插入图片描述

根据上面的分析,编写程序如下:

%%time
# 冒泡排序
def bubbleSort(a):
    # 首先获取列表list的总长度,为之后循环比较做准备
    n = len(a)
    # 进行 n-1 次比较,控制比较的轮数
    i = 1
    while i <= n-1:
        # 控制每轮比较的次数
        j = 0
        while j < n-i:
            # 交换
            if a[j] > a[j+1]:
                t = a[j]
                a[j] = a[j+1]
                a[j+1] = t
            j += 1
        i += 1
    # 打印每一轮交换后的列表
    for a1 in a:
        print(a1, end=" ")

if __name__=="__main__":
    print("请为列表元素赋初值,列表末尾不能有空格:")
    x = input()
    a = x.split(" ")                                        # 以空格方式分割每个元素
    for i in range(0, len(a)):              # 输入多个值
        a[i] = int(a[i])
    print("你输入的列表元素为:\n", a)
    print("经过交换后的数组元素为:")
    bubbleSort(a)
请为列表元素赋初值,列表末尾不能有空格:
你输入的列表元素为:
 [5, 7, 9, 8, 2, 3, 1, 6, 4]
经过交换后的数组元素为:
1 2 3 4 5 6 7 8 9 CPU times: user 195 ms, sys: 53.3 ms, total: 248 ms
Wall time: 24.6 s

5.问题拓展

常用的排序方法除了上述的冒泡法外,还有选择排序、插入排序、快速排序、堆排序等,下面简单介绍选择排序。

选择排序的思想是:扫描整个线性表,第一轮比较拿数组中的第一个元素与其他元素进行比较,遇到比第一个元素小的元素则进行交换,再拿着交换之后的第一个元素接着从上次比较的位置与后面的元素进行比较,直到扫描到线性表的最后,从中选出最小的元素,将它交换到表的最前面(这是它应有的位置);第二轮比较的时候从第二个元素开始,依次与第三个、第四个直到最后一个进行比较,在比较过程中有比第二个元素小的元素则进行交换,接着与后面的元素比较;对剩下的子表采用同样的方法,直到子表为空。在最坏的情况下,需要比较n(n-1)/2次。

完整的程序如下:

%%time
# 选择排序
def selectionSort(a):
    # 求出列表的长度
    n = len(a)

    for i in range(0, n-1):
        for j in range(i+1, n):
            #交换
            if a[j] < a[i]:
                t = a[i]
                a[i] = a[j]
                a[j] = t
    for i in a:
        print(i, end=" ")

if __name__=="__main__":
    print("请为列表元素赋初值,列表末尾不能有空格:")
    x = input()
    a = x.split(" ")                                        # 以空格方式分割每个元素
    for i in range(0, len(a)):              # 输入多个值
        a[i] = int(a[i])
    print("你输入的列表元素为:\n", a)
    print("经过交换后的数组元素为:")
    selectionSort(a)
    print("\n")
请为列表元素赋初值,列表末尾不能有空格:
你输入的列表元素为:
 [5, 7, 9, 8, 2, 3, 1, 6, 4]
经过交换后的数组元素为:
1 2 3 4 5 6 7 8 9 

CPU times: user 124 ms, sys: 35.4 ms, total: 159 ms
Wall time: 15.5 s

不同排序法的效率是不同的,不同需求情况下可选择不同的方法。其他几种排序方法的原理有兴趣的读者可参阅数据结构的相关内容。

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

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

相关文章

波特率和(FSK)调制速率的关系

最近在学习基于STM32的FSK解调&#xff0c;刚开始一直对波特率和FSK调制速率两者的概念有些混淆&#xff0c;于是出一篇帖子进行总结。 在百度百科中查到&#xff1a; 调制速率定义 在电子通信领域&#xff0c;调制速率&#xff0c;指的是信号被调制以后在单位时间内的变化&am…

软考学习--计算机组成原理与体系结构

计算机组成原理与体系结构 数据的表示 进制转换 R 进制转换为 10 进制–按权展开法 10进制转换为2进制 原码 反码 补码 移码 原码 &#xff1a;数字的二进制表示反码 &#xff1a; 正数的反码等于原码&#xff0c;负数的反码等于原码取反补码&#xff1a; 正数的补码等…

大模型之二十二 OpenAI sora

2024年2月15日在中国新年还没过完的时候&#xff0c;OpenAI 发布的Sora&#xff0c;这是AI视频生成领域的‘Midjourney时刻’&#xff0c;Sora将Diffusion模型和Transformer模型相结合&#xff0c;在视觉领域实现了大语言模型类似的突破&#xff0c;这将类似于ChatGPT一样&…

【Python笔记-设计模式】工厂模式

一、说明 (一) 解决问题 提供了一种方式&#xff0c;在不指定具体类将要创建的情况下&#xff0c;将类的实例化操作延迟到子类中完成。可以实现客户端代码与具体类实现之间的解耦&#xff0c;使得系统更加灵活、可扩展和可维护。 (二) 使用场景 希望复用现有对象来节省系统…

怎样连接局域网?

局域网&#xff08;Local Area Network&#xff0c;缩写为LAN&#xff09;是建立在小范围内的计算机网络&#xff0c;用于连接同一建筑物或者办公场所内的设备。连接局域网可以实现设备之间的信息共享和远程通信。本文将介绍如何连接局域网&#xff0c;并介绍了天联组网天联的使…

unity学习(15)——服务器组装(1)

1.新建好的c#项目如下&#xff1a; 文件夹中内容如下&#xff1a; 此时已经可以通过vs2022打开.sln文件&#xff0c;就可以打开项目了。 2.我们把逆向后&#xff08;主程序&#xff09;的内容的代码粘贴过去。有些逆向功底&#xff0c;很快可以定位到&#xff0c;服务器的入口…

强国有我社会实践公益活动在合肥市庐阳区开展

2月18日是开工第一天&#xff0c;阳光灿烂、春光明媚。合肥市四十五中2022级星辰&#xff08;5&#xff09;班部分同学在监护人的陪伴下来到庐阳区双岗街道万小店社区残疾人工作站&#xff0c;和工作站兄弟姐妹们共同开展“强国复兴有我”社会实践公益活动。合肥市庐阳区为民社…

基于JavaWeb开发的小区车辆登记系统计算机毕设[附源码]

基于JavaWeb开发的小区车辆登记系统计算机毕设[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统…

C++ bfs反向建图(六十)【第七篇】

今天我们来学习一下bfs反向建图 1.bfs的反向建图 我们之前在图上求最短路都是求从起点出发到每个点的最短路&#xff0c;不过有时候我们也会遇到让求每个点到终点的最短路的问题&#xff0c;此时我们可以怎么做呢&#xff1f; 如果从每个点出发&#xff0c;用 BFS 搜索到终点…

基于JavaWeb开发的羽毛球管理系统计算机毕业设计[附源码]

基于JavaWeb开发的羽毛球管理系统计算机毕业设计[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系…

Linux环境安装Maven(详细图文)

目录 摘要 一、准备工作 1.检查当前环境是否安装maven 2.下载maven ​3.上传maven压缩包 4.解压maven包 5.移动到/usr/local目录下方便管理 6.配置maven环境变量 7.刷新配置文件 8.配置maven镜像仓库 9.验证是否成功 摘要 笔者Linux环境为&#xff1a;Ubuntu 22.04 …

C#上位机与三菱PLC的通信07--使用第3方通讯库读写数据

1、通讯库介绍 mcprotocol 是一个基于 Node.js 的三菱 PLC MC 协议通信库&#xff0c;具有以下特点&#xff1a; 支持多种三菱 PLC MC 协议的设备&#xff0c;如 FX3U、Q03UDECPU、QJ71E71 等。 支持多种功能码和数据类型&#xff0c;如读取线圈&#xff08;M&#xff09;、…

Yii2项目使用composer异常记录

问题描述 在yii2项目中&#xff0c;使用require命令安装依赖时&#xff0c;出现如下错误提示 该提示意思是&#xff1a;composer运行时&#xff0c;执行了yiisoft/yii2-composer目录下的插件&#xff0c;但是该插件使用的API版本是1.0&#xff0c;但是当前的cmposer版本提供的…

【JVM篇】什么是类加载器,有哪些常见的类加载器

文章目录 &#x1f354;什么是类加载器&#x1f6f8;有哪些常见的类加载器 &#x1f354;什么是类加载器 负责在类加载过程中&#xff0c;将字节码信息以流的方式获取并加载到内存当中 &#x1f6f8;有哪些常见的类加载器 启动类加载器 启动类加载器是有Hotspot虚拟机通过的类…

一文了解Web3.0真实社交先驱ERA

Web2时代&#xff0c;少数科技巨头垄断了全球近60亿人口的网络社交数据&#xff0c;并用之为自己牟利&#xff0c;用户无法掌控个人数据&#xff0c;打破该局面逐渐成为共识&#xff0c;于是&#xff0c;不少人看到了Web3社交赛道蕴含的巨大机遇&#xff0c;标榜着去中心化和抗…

官网域名SSL证书的重要性

什么是SSL证书&#xff1f; SSL&#xff08;安全套接层&#xff09;证书是一种加密技术&#xff0c;用于确保在用户浏览网站时&#xff0c;其数据传输经过安全通道&#xff0c;不能被第三方窃取或篡改。通过SSL证书&#xff0c;网站可以建立安全连接&#xff0c;保障用户与网站…

阿里云学生300元无门槛代金券领取入口,2024更新

阿里云300元无门槛代金券怎么领取&#xff1f;300元无门槛代金券是指阿里云的「云工开物」高校计划&#xff0c;学生完成实名认证即可领取300元无门槛优惠券&#xff0c;活动入口 aliyunbaike.com/go/university 活动的打开后&#xff0c;如下图&#xff1a; 阿里云学生代金券…

【自然语言处理】:实验4布置,预训练语言模型实现与应用

清华大学驭风计划 因为篇幅原因实验答案分开上传&#xff0c;自然语言处理专栏持续更新中&#xff0c;期待的小伙伴敬请关注 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 案例简介 2018年&#xff0c;Google提出了预训练语言模型BE…

甲醇汽车产量不断增加 行业发展面临一定困难和挑战

甲醇汽车产量不断增加 行业发展面临一定困难和挑战 甲醇汽车是指以甲醇作为主要或者唯一燃料的汽车。与传统汽车相比&#xff0c;甲醇汽车具有节能减排、使用成本低、有害气体排放量少等优点&#xff0c;能够有效缓解能源紧缺及环境污染问题。 从上游市场来看&#xff0c;甲醇…

策略联动配置

策略联动简介 定义 策略联动是通过在网关设备上统一管理用户的访问策略并且在网关设备和认证接入设备执行用户的访问策略&#xff0c;来解决大型园区策略强度与复杂度之间矛盾的一种解决方案。 目的 传统网络中&#xff0c;在接入层部署NAC认证&#xff0c;使得认证接入设备…