【C语言】排序详解——冒泡排序
前言:
冒泡排序可以说是排序系列中最简单也最基础的一种排序的方式,尽管它十分的简单易懂,但依旧会有一些小问题是大家可能忽略的,因此我打算将不同排序分成单独的文章进行讲解,这样既不会显得臃肿,同时也可以讲得更加仔细,废话不多说,开干。
一.概念简述
从上图我们不难看出冒泡排序应该有两个循环:第一个循环是小循环,该循环的作用是——在某个数组内依次进行两个数的大小比较;第二个循环是大循环,该循环的作用是——决定小循环的次数
那么概括来说就是,在一定次数内,数组按照一定的大小顺序进行两两比较,满足顺序的移动
基本代码:
既然已经了解了冒泡排序的执行方式,那么就不难写出代码了,那么先直接给出代码:
#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语言】排序详解——冒泡排序相关推荐
- c语言排序常用问题,【更新中】【排序详解】解决排序问题(以C语言为例)
[更新中][排序详解]解决排序问题(以C语言为例) [更新中][排序详解]解决排序问题(以C语言为例) 文章目录 排序的相关概念 简单排序 一.插入排序: (一)插入排序基本思想 (二)插入排序基本操 ...
- 【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序
[排序]什么都能排的C语言qsort排序详解[超详细的宝藏级别教程]深度理解qsort排序 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客之前,博主在这里 ...
- Sorting 排序详解(c语言实现)
Sorting 排序详解(c语言实现)# 今日突然有任务,明天补充完整. 邮箱:Is_Dmy@163.com期待交流. Hello,各位小伙伴~我是你们的课代表橙橙,今天呢我要给大家分享的是关于内排序 ...
- js排序算法详解-冒泡排序
全栈工程师开发手册 (作者:栾鹏) js系列教程5-数据结构和算法全解 js排序算法详解-冒泡排序 1.1 原始人冒泡排序 function bubbleSort(arr) {var len = ar ...
- c语言的指针详解ppt,最全的C语言指针详解.ppt
最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...
- shell编程数组与冒泡算法排序详解
shell编程数组与冒泡算法排序详解 一 数组的四种表达方式 二 数组的增删改查操作 三 数组传参 3.1 主程序向函数传数组参数 3.2 从函数返回数组到主程序 四 冒泡算法排序 一 数组的四种表达 ...
- R语言——数据类型详解
R语言--数据类型详解 R语言支持的数据类型 数值型 整数型 逻辑型 字符型 复数型 原生型 R语言的数据对象类型包括 向量:一个向量只能有一种数据类型 矩阵:一个矩阵只能有一种数据类型 数组:一个数 ...
- 归并排序过程实现c语言,C语言归并排序详解
C语言归并排序详解 发布日期:2015-12-31 11:16 来源: 标签: 编程语言 C教程 C语言归并排序 C语言归并排序算法 本章我们主要学习C语言实现排序算法之归并排序,对归并排序的原理及实 ...
- 秒懂的shell编程数组与冒泡算法排序详解
shell编程数组与冒泡算法排序详解 一.数组的四种表达方式 二 .数组的增删改查操作 三 .数组传参 3.1 主程序向函数传数组参数 3.2 从函数返回数组到主程序 四 .冒泡算法排序 一.数组的四 ...
- c语言数组详解视频,C语言数组详解
<C语言数组详解>由会员分享,可在线阅读,更多相关<C语言数组详解(55页珍藏版)>请在人人文库网上搜索. 1.就是一组具有固定数目的.有序的.类型相同的数据的集合.根据数组下 ...
最新文章
- ubuntu 挂载 exfat 格式 U盘 mount:unknown filesystem type ‘exfat‘
- vlookup示例_VLOOKUP示例–如何在Excel中执行VLOOKUP
- Activity应用场景解析
- 在家办公的第一天,钉钉、企业微信集体“崩溃”...
- 【JavaEE WEB 开发】Tomcat 详解 Servlet 入门
- 导入jQuery库时应该注意的问题
- UVA11255 Necklace Burnside、组合
- Linux——CentOS安装桌面
- 爬一爬那些年你硬盘存过的老师
- PHP 7.2 新功能介绍
- 在nocdb转pdb的时候遇到小bug
- mysql 5.6 ibdata1_mysql 里的 ibdata1 文件不断的增长?
- 深入理解C++中的RVO
- Python静态作用域名字搜索规则
- github开源项目大集合(1)
- idea运行springboot出现 Disconnected from the target VM, address: ‘127.0.0.1:xxxx‘, transport: ‘socket‘
- matlab转自张朋飞
- Java刷题面试系列习题(三)
- 免安装版的Mysql安装与配置——详细教程
- imx6ul spi 设备驱动开发
热门文章
- 设计【SPFA】【差分约束】
- OOP之C#设计及其UML(反向工程)
- [转]Spring 注解总结
- 无IDE时,使用支持HTML5的浏览器作编辑器的方法
- 【C语言】15-预处理指令1-宏定义
- 易语言PHP非对称加密,openssl调用大集合[易语言源码] | 贝贝吧
- _stdcall函数调用约定详解
- 温习下 function pointer.
- 搭建Demo验证在一次Socket请求中有借助缓冲区处理数据
- python怎么读取dat类型文件_基于python批量处理dat文件及科学计算方法详解