前言:

冒泡排序可以说是排序系列中最简单也最基础的一种排序的方式,尽管它十分的简单易懂,但依旧会有一些小问题是大家可能忽略的,因此我打算将不同排序分成单独的文章进行讲解,这样既不会显得臃肿,同时也可以讲得更加仔细,废话不多说,开干。

一.概念简述

从上图我们不难看出冒泡排序应该有两个循环:第一个循环是小循环,该循环的作用是——在某个数组内依次进行两个数的大小比较;第二个循环是大循环,该循环的作用是——决定小循环的次数

那么概括来说就是,在一定次数内,数组按照一定的大小顺序进行两两比较,满足顺序的移动

基本代码:

既然已经了解了冒泡排序的执行方式,那么就不难写出代码了,那么先直接给出代码:

#include<stdio.h>
const int N = 1e5;
int a[N];void swap(int &x,int &y){int t = x;x = y;y = t;
}//交换数字函数
//这是降序
int main()
{int n;scanf("%d",&n);for(int i = 0; i < n; i ++)scanf("%d",&a[i]);//冒泡排序for(int i = 1; i <= n; i ++){for(int j = 0; j < n; j ++){if(a[j]<a[j + 1])swap(a[j],a[j + 1]);}}for(int i = 0; i < n; i ++)printf("%d",a[i]);return 0;
}

接下来是对该代码的分析:

1.大循环:

for(int i = 1; i <= n; i++)

大循环的作用是决定小循环的次数,可次数是多少呢?其实我们不难看出每经过一次循环就会有一个数被固定在右边,也就是图片上的黄色部分,所以我们可以得出次数其实就是一个数组内元素的个数,这样大循环就建立起来了;

2.小循环:

for(int j = 0; j < n; j ++){if(a[j]<a[j - 1])swap(a[j],a[j - 1]);}

小循环很简单,就是两两比较,进行交换。

代码优化:

优化一:

小循环的顺序:通常来说我们都采用从0开始循环。对于一般题来说没有问题,但如果你用冒泡排序做字符串排序,并且排序方式是升序,那么就会出现问题。

#include<stdio.h>
#include<string.h>
void swap(char &x,char &y){char t = x;x = y;y = t;
}
int main()
{char a[100];scanf("%s",a);int len = strlen(a);for(int i = 1; i <= len; i ++){for(int j = 0; j < len; j ++){if(a[j]>a[j + 1])swap(a[j],a[j + 1]);}}puts(a);return 0;
}

这个是一个将字符串以升序的方式进行排列的代码,乍一看没有问题,实际上暗藏陷阱。

当我们输入“zxcvb”,得到的结果却是一个空行,那么这是为什么呢?

我们先解析一下字符串:

{'z','x','c','v','b','/0'};

结果已经很明显了,就是因为每个字符串都是以'/0'结尾的,而这个是会被编译器识别的,同时它又比前面的所有字符都小,因此它毫不意外的就会被放到最前面,得到的结果就是

{'/0','z','x','c','v','b'};

而当我们编辑器输出时,一旦遇到‘/0’,就等于是告诉它,可以了,你不用在往后运行了。所有最后我们看到的就是一片空白。

那么改良过的代码就是:

#include<stdio.h>
const int N = 1e5;
int a[N];void swap(int &x,int &y){int t = x;x = y;y = t;
}//交换数字函数
//这是降序
int main()
{int n;scanf("%d",&n);for(int i = 0; i < n; i ++)scanf("%d",&a[i]);//冒泡排序for(int i = 1; i <= n; i ++){for(int j = n-1; j >= 0; j --){if(a[j]<a[j - 1])swap(a[j],a[j - 1]);}}for(int i = 0; i < n; i ++)printf("%d",a[i]);return 0;
}

其实大体没变,就是将小循环变成了从后开始循环。

优化二:减少运行时间

其实通过最上面的动态图片我们可以看到,每经过一次大循环,就会有一个数被放在了最左面,而这个数在之后的循环中是不会在发生改变的,而这也是我们优化的出发点。

#include<stdio.h>
const int N = 1e5;
int a[N];void swap(int &x,int &y){int t = x;x = y;y = t;
}//交换数字函数
//这是降序
int main()
{int n;scanf("%d",&n);for(int i = 0; i < n; i ++)scanf("%d",&a[i]);//冒泡排序for(int i = 1; i <= n; i ++){for(int j = n-1; j >= i; j --){if(a[j]<a[j - 1])swap(a[j],a[j - 1]);}}for(int i = 0; i < n; i ++)printf("%d",a[i]);return 0;
}

其实这个代码只改了一小个地方,就是将小循环的 (j >= 0)改成了(j >= i),为啥可以这样改呢。因为之前我们讲过大循环的意义是决定小循环的次数,那么i就代表了这是第几次循环,也就代表了已经有几个数被固定在了左边(根据优化一可知我们已经把小循环改成了从左到右循环,所以固定在了左边),而这些被固定的数其实是不需要再进行两两比较的。

给出最终的优化代码:

#include<stdio.h>
const int N = 1e5;
int a[N];void swap(int &x,int &y){int t = x;x = y;y = t;
}//交换数字函数
//这是降序
int main()
{int n;scanf("%d",&n);for(int i = 0; i < n; i ++)scanf("%d",&a[i]);//冒泡排序for(int i = 1; i <= n; i ++){for(int j = n-1; j >= i; j --){if(a[j]<a[j - 1])swap(a[j],a[j - 1]);}}for(int i = 0; i < n; i ++)printf("%d",a[i]);return 0;
}

感谢你的阅读,本人蒟蒻,如果有不正确之处欢迎指出。下一个排序是桶排。

【C语言】排序详解——冒泡排序相关推荐

  1. c语言排序常用问题,【更新中】【排序详解】解决排序问题(以C语言为例)

    [更新中][排序详解]解决排序问题(以C语言为例) [更新中][排序详解]解决排序问题(以C语言为例) 文章目录 排序的相关概念 简单排序 一.插入排序: (一)插入排序基本思想 (二)插入排序基本操 ...

  2. 【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序

    [排序]什么都能排的C语言qsort排序详解[超详细的宝藏级别教程]深度理解qsort排序 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客之前,博主在这里 ...

  3. Sorting 排序详解(c语言实现)

    Sorting 排序详解(c语言实现)# 今日突然有任务,明天补充完整. 邮箱:Is_Dmy@163.com期待交流. Hello,各位小伙伴~我是你们的课代表橙橙,今天呢我要给大家分享的是关于内排序 ...

  4. js排序算法详解-冒泡排序

    全栈工程师开发手册 (作者:栾鹏) js系列教程5-数据结构和算法全解 js排序算法详解-冒泡排序 1.1 原始人冒泡排序 function bubbleSort(arr) {var len = ar ...

  5. c语言的指针详解ppt,最全的C语言指针详解.ppt

    最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...

  6. shell编程数组与冒泡算法排序详解

    shell编程数组与冒泡算法排序详解 一 数组的四种表达方式 二 数组的增删改查操作 三 数组传参 3.1 主程序向函数传数组参数 3.2 从函数返回数组到主程序 四 冒泡算法排序 一 数组的四种表达 ...

  7. R语言——数据类型详解

    R语言--数据类型详解 R语言支持的数据类型 数值型 整数型 逻辑型 字符型 复数型 原生型 R语言的数据对象类型包括 向量:一个向量只能有一种数据类型 矩阵:一个矩阵只能有一种数据类型 数组:一个数 ...

  8. 归并排序过程实现c语言,C语言归并排序详解

    C语言归并排序详解 发布日期:2015-12-31 11:16 来源: 标签: 编程语言 C教程 C语言归并排序 C语言归并排序算法 本章我们主要学习C语言实现排序算法之归并排序,对归并排序的原理及实 ...

  9. 秒懂的shell编程数组与冒泡算法排序详解

    shell编程数组与冒泡算法排序详解 一.数组的四种表达方式 二 .数组的增删改查操作 三 .数组传参 3.1 主程序向函数传数组参数 3.2 从函数返回数组到主程序 四 .冒泡算法排序 一.数组的四 ...

  10. c语言数组详解视频,C语言数组详解

    <C语言数组详解>由会员分享,可在线阅读,更多相关<C语言数组详解(55页珍藏版)>请在人人文库网上搜索. 1.就是一组具有固定数目的.有序的.类型相同的数据的集合.根据数组下 ...

最新文章

  1. ubuntu 挂载 exfat 格式 U盘 mount:unknown filesystem type ‘exfat‘
  2. vlookup示例_VLOOKUP示例–如何在Excel中执行VLOOKUP
  3. Activity应用场景解析
  4. 在家办公的第一天,钉钉、企业微信集体“崩溃”...
  5. 【JavaEE WEB 开发】Tomcat 详解 Servlet 入门
  6. 导入jQuery库时应该注意的问题
  7. UVA11255 Necklace Burnside、组合
  8. Linux——CentOS安装桌面
  9. 爬一爬那些年你硬盘存过的老师
  10. PHP 7.2 新功能介绍
  11. 在nocdb转pdb的时候遇到小bug
  12. mysql 5.6 ibdata1_mysql 里的 ibdata1 文件不断的增长?
  13. 深入理解C++中的RVO
  14. Python静态作用域名字搜索规则
  15. github开源项目大集合(1)
  16. idea运行springboot出现 Disconnected from the target VM, address: ‘127.0.0.1:xxxx‘, transport: ‘socket‘
  17. matlab转自张朋飞
  18. Java刷题面试系列习题(三)
  19. 免安装版的Mysql安装与配置——详细教程
  20. imx6ul spi 设备驱动开发

热门文章

  1. 设计【SPFA】【差分约束】
  2. OOP之C#设计及其UML(反向工程)
  3. [转]Spring 注解总结
  4. 无IDE时,使用支持HTML5的浏览器作编辑器的方法
  5. 【C语言】15-预处理指令1-宏定义
  6. 易语言PHP非对称加密,openssl调用大集合[易语言源码] | 贝贝吧
  7. _stdcall函数调用约定详解
  8. 温习下 function pointer.
  9. 搭建Demo验证在一次Socket请求中有借助缓冲区处理数据
  10. python怎么读取dat类型文件_基于python批量处理dat文件及科学计算方法详解