【算法】邻居好说话——冒泡排序

2023-11-18

 简化版的桶排序不仅仅有上一节所遗留的问题,更要命的是:它非常浪费空间!例如需要排序数的范围是0~2100000000之间,那你则需要申请2100000001个变量,也就是说要写成int a[2100000001]。因为我们需要用2100000001个“桶”来存储0~2100000000之间每一个数出现的次数。即便只给你5个数进行排序(例如这5个数是1,1912345678,2100000000,18000000和912345678),你也仍然需要2100000001个“桶”,这真是太浪费了空间了!还有,如果现在需要排序的不再是整数而是一些小数,比如将5.56789,2.12,1.1,3.123,4.1234这五个数进行从小大排序又该怎么办呢?现在我们来学习另一种新的排序算法:冒泡排序。它可以很好的解决这两个问题。


  冒泡排序的基本思想是:每次比较两个相邻的元素,如果他们的顺序错误就把他们交换过来。
  例如我们需要将12 35 99 18 76这5个数进行从大到小进行排序。既然是从大到小排序也就是说越小的越靠后,你是不是觉得我在说废话,但是这句话很关键(∩_∩)。
  首先比较第1位和第2位的大小,现在第1位是12,第2位是35。发现12比35要小,因为我们希望越小越靠后嘛,因此需要交换这两个数的位置。交换之后这5个数的顺序是35 12 99 18 76。
  按照刚才的方法,继续比较第2位和第3位的大小,第2位是12,第3位是99。12比99要小,因此需要交换这两个数的位置。交换之后这5个数的顺序是35 99 12 18 76。
  根据刚才的规则,继续比较第3位和第4位的大小,如果第3位比第4位小,则交换位置。交换之后这5个数的顺序是35 99 18 12 76。
  最后,比较第4位和第5位。4次比较之后5个数的顺序是35 99 18 76 12。
  经过4次比较后我们发现最小的一个数已经就位(已经在最后一位,请注意12这个数的移动过程),是不是很神奇。现在再来回忆一下刚才比较的过程。每次都是比较相邻的两个数,如果后面的数比前面的数大,则交换这两个数的位置。一直比较下去直到最后两个数比较完毕后,最小的数就在最后一个了。就如同是一个气泡,一步一步往后“翻滚”,直到最后一位。所以这个排序的方法有一个很好听的名字“冒泡排序”。
121415da1aevwg0gzfva0i.png
  说道这里其实我们的排序只将5个数中最小的一个归位了。每将一个数归位我们将其称为“一趟”。下面我们将继续重复刚才的过程,将剩下的4个数一一归位。
  好现在开始“第二趟”,目标是将第2小的数归位。首先还是先比较第1位和第2位,如果第1位比第2位小,则交换位置。交换之后这5个数的顺序是99 35 18 76 12。接下来你应该都会了,依次比较第2位和第3位,第3位和第4位。注意此时已经不需要再比较第4位和第5位。因为在第一趟结束后已经可以确定第5位上放的是最小的了。第二趟结束之后这5个数的顺序是99 35 76 18 12。
  “第三趟”也是一样的。第三趟之后这5个数的顺序是99 76 35 18 12。
  现在到了最后一趟“第四趟”。有的同学又要问了,这不是已经排好了吗?还要继续?当然,这里纯属巧合,你可以用别的数试一试可能就不是了。你能找出这样的数据样例来吗?请试一试。
  “冒泡排序”原理是:每一趟只能确定将一个数归位。即第一趟只能确定将末位上的数(既第5位)归位,第二趟只能将倒数第2位上的数(既第4位)归位,第三趟只能将倒数第3位上的数(既第3位)归位,而现在前面还有两个位置上的数没有归位,因此我们仍然需要进行“第四趟”。
  “第四趟”只需要比较第1位和第2位的大小。因为后面三个位置上的数归位了,现在第1位是99,第2位是76,无需交换。这5个数的顺序不变仍然是99 76 35 18 12。到此排序完美结束了,5个数已经有4个数归位,那最后一个数也只能放在第1位了。
  最后我们总结一下:如果有n个数进行排序,只需将n-1个数归位,也就是说要进行n-1趟操作。而“每一趟”都需要从第1位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较(已经归位的数你还比较个啥,浪费表情)。

  这个算法是不是很强悍。记得我每次拍集体照的时候就总是被别人换来换去的,当时特别烦。不知道发明此算法的人当时的灵感是否来源于此。罗里吧嗦地说了这么多,下面是代码。建议先自己尝试去实现一下看看,再来看我是如何实现的。

#include <stdio.h>
int main()
{
  int a[100],i,j,t,n;
    scanf("%d",&n);  //输入一个数n,表示接下来有n个数
    for(i=1;i<=n;i++)  //循环读入n个数到数组a中
        scanf("%d",&a[i]);
    //冒泡排序的核心部分
    for(i=1;i<=n-1;i++) //n个数排序,只用进行n-1趟
    {
        for(j=1;j<=n-i;j++) //从第1位开始比较直到最后一个尚未归位的数,想一想为什么到n-i就可以了。
        {
            if(a[j]<a[j+1]) //比较大小并交换
            {  t=a[j]; a[j]=a[j+1]; a[j+1]=t;  }
        }
    }
    for(i=1;i<=n;i++)  //输出结果
        printf("%d ",a[i]);
    getchar();getchar();
    return 0;
}

可以输入以下数据进行验证

1081005022156110009990

  运行结果是

01681522501009991000
将上面代码稍加修改,就可以解决第1节遗留的问题,如下。
#include <stdio.h>
struct student
{
    char name[21];
    char score;
};//这里创建了一个结构体用来存储姓名和分数
int main()
{
    struct student a[100],t;
    int i,j,n;
    scanf("%d",&n); //输入一个数n
    for(i=1;i<=n;i++) //循环读入n个人名和分数
scanf("%s %d",a[i].name,&a[i].score);
    //按分数从高到低进行排序
    for(i=1;i<=n-1;i++)
    {
        for(j=1;j<=n-i;j++)
        {
            if(a[j].score<a[j+1].score)//对分数进行比较
            {  t=a[j]; a[j]=a[j+1]; a[j+1]=t;  }
        }
    }
    for(i=1;i<=n;i++)//输出人名
        printf("%s\n",a[i].name);
    getchar();getchar();
    return 0;
}

可以输入以下数据进行验证

5

huhu 5

haha 3

xixi 5

hengheng 2

gaoshou 8

  运行结果是

gaoshou

huhu

xixi

haha

hengheng

冒泡排序的核心部分是双重嵌套循环。不难看出冒泡排序的时间复杂度是O(N2)。这是一个非常高的时间复杂度。冒泡排序早在1956年就有人开始研究,之后有很多人都尝试过对冒泡排序进行改进,但结果却令人失望。如Knuth(Donald E. Knuth中文名为高德纳,1974年图灵奖获得者)所说:“冒泡排序除了它迷人的名字和导致了某些有趣的理论问题这一事实之外,似乎没有什么值得推荐的。”你可能要问:那还有没有更好的排序算法呢?请期待下周更新——快速排序。

http://bbs.ahalei.com/thread-4400-1-1.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法】邻居好说话——冒泡排序 的相关文章

随机推荐

  • 武汉工程大学计算机科学与工程学院调剂公告,武汉工程大学计算机科学与工程学院2017年考研复试安排...

    武汉工程大学计算机科学与工程学院2017年考研复试安排本站小编 免费考研网 2017 07 23 武汉工程大学计算机科学与工程学院 以下简称 本院 2017年硕士研究生复试工作将于2017年3月18日 2017年3月20日进行 具体安排如下
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 大数据三道习题

    Lambda 架构设计图 Lambda体系架构的优点 鲁棒性和容错能力 由于批处理层被设计为追加式 即包含了自开始以来的整体数据集 因此该系统具有一定的容错能力 如果任何数据被损坏 该架构则可以删除从损坏点以来的所有数据 并替换为正确的数据
  • OpenCV源码编译xfeatures2d.VGG出错解决

    OpenCV源码编译xfeatures2d VGG出错解决 在使用OpenCV进行计算机视觉任务时 xfeatures2d模块是一个非常有用的工具 它提供了许多先进的特征检测和描述算法 其中之一是VGG算法 它是一种基于深度学习的图像描述算
  • Qt启动页多线程

    Qt启动页多线程 项目需要在Qt进入启动页之前加载一个大模型文件 同时要有一个页面用来提示用户加载状态 这里就需要用到多线程了 如果在单线程操作 要么需要等到文件加载完毕后才能显示等待页 要么干脆跳过了模型文件的加载 都是不符合需求的 我们
  • python中的且和或怎么表示_python中逻辑与或(and、or)和按位与或异或(&、

    按位与或 按照二进制进行逻辑运算 例如 数字换成二进制 各自位上的0 1进行逻辑运算 得到的结果转换为数字 3 2 0111 0010 0010 2 二进制逻辑运算规则 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 1 1
  • 软件测试复习(4)----测试用例的编写

    软件测试的编写有这几大不可缺少的元素 测试目标 测试环境 输入数据 步骤 期望结果 看例题 根据如下登录界面设计两个测试用例 设计两个测试用例 我们可以从正反两面设计 设计一个正确成功登录的用例 再设计一个登录失败的用例 测试用例1 测试目
  • 大数据与人工智能入门到放弃(01 回顾篇linux--网络,服务,克隆)

    前言 为了从头到尾的搞透 了解运用 大数据和AI 所以从今天开始 决定从头开始 从0开始回顾 到项目实战 在工作之余能抽出时间来完善大数据和AI的学习的过程 所以会从项目的搭建过程开始做起 每周至少3次更新博客 希望不会放弃 做这些记录的原
  • mybatis-plus之代码生成器07

    mybatis plus之代码生成器07 AutoGenerator 是 MyBatis Plus 的代码生成器 通过 AutoGenerator 可以快速生成 Entity Mapper Mapper XML Service Contro
  • 百度网盘无法登陆,二维码不显示,密码、验证码登陆显示‘网络异常’解决方法

    如图所示 二维码加载不出来 账号也不能登陆 但是其他软件一切正常 IE重置 防火墙 注册表 卸载重装 各种方法都无法解决 解决办法 连接手机WiFi后二维码加载出来 问题解决 所以换一个网登陆就可以了
  • linux 和 windows usb插拔侦测

    1 windowsU口探测事件 设备事件 WM DEVICECHANGE 首先要创建一个窗口 把设备事件和窗口关联 HWND h CreateWindow TEXT USB EVENT TEXT 0 0 0 0 0 0 0 GetModul
  • c语言经典程序合集

    1 c语言计算自然数之和 计算自然数和 include
  • SpringBoot+ Mybatis plus 配置多个数据源 (MySql)

    首先配置 yml 然后创建对应的 配置文件 然后复制下方的代码 进行粘贴 Configuration MapperScan basePackages com example chassis mapper chassis mapper sql
  • 关于一个栈的输入顺序是a,b,c,d,e则下列序列中不可能是出栈顺序

    经常在笔试的时候会看见这样类似的笔试题 就是关于一个栈的输入顺序是a b c d e则下列序列中不可能是出栈顺序 很多人都知道栈是先进后出 但是还是做好这道题 以一道题目为例给大家讲讲这道题目应该怎么做 题目 一个栈的输入顺序是a b c
  • 【Linux】深入理解文件操作

    文章目录 初次谈论文件 重温C语言文件操作 系统文件操作接口 open write read 再次谈论文件 文件描述符 文件描述符的分配规则 重定向 什么是重定向 重定向的本质 系统调用接口实现重定向 lt gt gt gt 初次谈论文件
  • Spring Boot中获取当前Request和Response实例的方法

    获取Request HttpServletRequest request ServletRequestAttributes RequestContextHolder getRequestAttributes getRequest 获取Res
  • uni-app在App平台如何实现升级更新?

    使用 uni app 开发 可将代码编译到iOS Android 微信小程序等多个平台 升级时也需考虑多平台同步升级 uni app发布为小程序的升级模式较简单 只需将开发完的代码提交小程序后台 待审核通过后用户将自动升级 App端的升级
  • STM32CubeIDE(串口)

    目录 一 轮询模式 1 1 配置USART2为异步模式 1 2 500ms发送一次消息 1 3 通信结果 1 4 串口控制LED 二 中断收发 2 1 开启中断 2 2 中断发送接收 2 2 1 中断发送只需要调用接口 2 2 2 中断接收
  • 二、文件管理命令

    2 文件管理命令 2 1文件管理 2 1 1touch新建文件指令 touch 当文件不存在时命令为新建文件 当文件存在时命令为修改文件时间戳 touch file1 file2 新建多个文件 touch t 11111111 11 修改文
  • 【算法】邻居好说话——冒泡排序

    简化版的桶排序不仅仅有上一节所遗留的问题 更要命的是 它非常浪费空间 例如需要排序数的范围是0 2100000000之间 那你则需要申请2100000001个变量 也就是说要写成int a 2100000001 因为我们需要用2100000