Python算法100例-1.8 冒泡排序

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

  • 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 = 1while i <= n-1:# 控制每轮比较的次数j = 0while j < n-i:# 交换if a[j] > a[j+1]:t = a[j]a[j] = a[j+1]a[j+1] = tj += 1i += 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] = tfor 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.mzph.cn/news/692102.shtml

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

相关文章

【Node.js】path 模块进行路径处理

Node.js 执行 JS 代码时&#xff0c;代码中的路径都是以终端所在文件夹出发查找相对路径&#xff0c;而不是以我们认为的从代码本身出发&#xff0c;会遇到问题&#xff0c;所以在 Node.js 要执行的代码中&#xff0c;访问其他文件&#xff0c;建议使用绝对路径 实例&#xff1…

040 构造器详解

无参构造器 当一个类未定义任何构造器时&#xff0c;代码编译后会自动生成一个无参构造器&#xff0c;如果只需要无参构造器就可以直接省略定义。 public class Person {public Person(){}String name;int age; }public class Person {String name;int age; }有参构造器 有参…

自定义表单工作流的优势特点有啥?

低代码技术平台是提升办公效率的得力武器&#xff0c;在当今竞争激烈的社会中获得了很多中小企业的喜爱与支持。流辰信息是一家专业研发低代码技术平台的服务商&#xff0c;IBPS开发平台用于很多行业中&#xff0c;助力企业实现了办公流程化。自定义表单工作流的优势多、简单灵…

RSA之前端加密后端解密

RSA之前端加密后端解密 RSA加密解密方式有&#xff1a; &#xff08;1&#xff09;公钥加密&#xff0c;私钥解密&#xff1b; &#xff08;2&#xff09;私钥加密&#xff0c;公钥解密&#xff1b; 此文章中以下我使用的是前端公钥加密&#xff0c;后端私钥解密&#xff1b; …

【点云配准】【深度学习】Windows11下PCRNet代码Pytorch实现与源码讲解

【点云配准】【深度学习】Windows11下PCRNet代码Pytorch实现与源码讲解 提示:最近开始在【点云配准】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【点云配准】【深度学习】Windows11下PCRNet代码Pytorch实现与源码讲解前言PCRNet模型运行环境…

Linux内核解读

来自鹅厂架构师 作者&#xff1a;aurelianliu 工作过程中遇到的调度、内存、文件、网络等可以参考。 1.os运行态 X86架构&#xff0c;用户态运行在ring3&#xff0c;内核态运行在ring0&#xff0c;两个特权等级。 &#xff08;1&#xff09;内核、一些特权指令&#xff0c;例…

debug - 只要在内存中有显示相关的数据, 就会被CE找到

文章目录 debug - 只要在内存中有显示相关的实际数据, 就会被CE找到概述笔记demo实现demo运行效果用CE查找实际数据地址找到自己的调试点 - 方法1找到自己的调试点 - 方法2打补丁备注END debug - 只要在内存中有显示相关的实际数据, 就会被CE找到 概述 自己写了一个demo, 想验…

人工智能_PIP3安装使用国内镜像源_安装GIT_普通服务器CPU_安装清华开源人工智能AI大模型ChatGlm-6B_002---人工智能工作笔记0097

接着上一节来看,可以看到,这里 创建软连接以后 [root@localhost Python-3.10.8]# ln -s /usr/local/python3/bin/python3 /usr/bin/python3 [root@localhost Python-3.10.8]# python3 -V Python 3.10.8 [root@localhost Python-3.10.8]# pwd /usr/local/Python-3.10.8 [root@…

Vue26 内置标签 v-text v-html

实例 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>v-text指令</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"></script></head><…

第一件事 什么是 Java 虚拟机 (JVM)

1、什么是虚拟机&#xff1f; - 这个其实是一个挺逗的事情&#xff0c;说白了&#xff0c;就是基于某个硬件架构&#xff0c;在这个硬件部署了一个操作系统&#xff0c;再构架一层虚拟的操作系统&#xff0c;这个新构架的操作系统就是虚拟机。 不知道的兄弟姐妹们&#xff0c;…

重学Java 18.学生管理系统项目

臣无祖母&#xff0c;无以至今日&#xff0c;祖母无臣&#xff0c;无以终余年 母孙二人&#xff0c;更相为命&#xff0c;是以区区不能废远 —— 陈情表.李密 —— 24.2.20 一、编写JavaBean public class Student {//学号private int id;//姓名private String name;//年龄pr…

Codeforces Round 925 (Div. 3)(A,B,C,D,E,F,G)

比赛链接 这场打的很顺&#xff0c;感觉难度和 div 4 差不多&#xff0c;不是很难。D题稍微考了考同余的性质&#xff0c;E题直接模拟过程即可&#xff0c;F题也可以暴力模拟或者拓扑排序&#xff0c;G题是个数学题&#xff0c;是个简单隔板法。A到F题都可以直接模拟就有点离谱…

「WinCC报警系统专题」简述“消息系统”

WinCC通过报警给操作员提供了有关过程故障和错误的信息。它们有助于尽早检测重要情况和避免停机时间。 一、消息系统 消息&#xff08;报警&#xff09;系统由组态和运行系统组件组成。 1、组态系统 报警记录编辑器&#xff08;如图1所示&#xff09;是报警系统的组态组件。报…

docker (九)-进阶篇-docker-compos最佳实践部署zabbix

一 部署docker环境 关闭防火墙、selinux、开启docker&#xff0c;并设置开机自启动 注意点&#xff1a;docker部署的时候&#xff0c;bip要指定&#xff0c;不然会导致虚拟机ip和容器ip冲突&#xff0c;ssh连不上虚拟机 部署请参考 docker &#xff08;二&#xff09;-yum…

为什么程序员不能一次性写好,需要不停改bug?

写程序不是一次性完成的原因有很多&#xff0c;其中包括了解不充分、需求变更、复杂性、人为因素等多个方面的原因。 需求不明确&#xff1a; 在项目一开始&#xff0c;对需求可能存在歧义或不完整的理解。有时候&#xff0c;业务需求会在开发过程中发生变化&#xff0c;导致…

Go应用性能分析实战

Go很适合用来开发高性能网络应用&#xff0c;但仍然需要借助有效的工具进行性能分析&#xff0c;优化代码逻辑。本文介绍了如何通过go test benchmark和pprof进行性能分析&#xff0c;从而实现最优的代码效能。原文: Profiling Go Applications in the Right Way with Examples…

【Vuforia+Unity】AR03-圆柱体物体识别

1.创建数据库模型 这个是让我们把生活中类似圆柱体和圆锥体的物体进行AR识别所选择的模型 Bottom Diameter:底部直径 Top Diameter:顶部直径 Side Length:圆柱侧面长度 请注意&#xff0c;您不必上传所有三个部分的图片&#xff0c;但您需要先为侧面曲面关联一个图像&#…

工具分享:在线键盘测试工具

在数字化时代&#xff0c;键盘作为我们与计算机交互的重要媒介之一&#xff0c;其性能和稳定性直接影响到我们的工作效率和使用体验。为了确保键盘的每个按键都能正常工作&#xff0c;并帮助用户检测潜在的延迟、连点等问题&#xff0c;一款优质的在线键盘测试工具显得尤为重要…

Java后端底座从无到有的搭建(随笔)

文章目录 开发模式的演变草创时期1.0时期&#xff08;基座时期&#xff09;1.1时期&#xff08;低代码时期&#xff09;2.0时期&#xff08;无代码时期&#xff09; 前言&#xff1a;本文是笔者在初创公司&#xff0c;一年多来Java后端服务底座搭建过程的总结&#xff0c;如有不…

四旋翼无人机控制-零散笔记整理

四旋翼无人机控制-零散笔记整理 说明仿真框架 说明 这是低创文章&#xff0c;本意是整理本科留下来的一堆零碎的纸质笔记&#xff0c;整理完就把纸质的扔了。所以前后不连贯&#xff0c;也可能有错误&#xff0c;图片都是直接拍的笔记照片&#xff0c;很丑。如果想系统学习的可…