java实现几种常用排序:冒泡排序
冒泡排序介绍
冒泡排序是我们得最多的排序方式之一,原因是简单易实现,且原理易懂。顾名思义,冒泡排序,它的排序过程就像水中的气泡一样,一个一个上浮到水面。

冒泡排序原理分析

冒泡排序代码实现
/**
* @Author {LearnAndGet}
* @Time 2019年1月8日
* @Discription:
*/
package com.sort;
import java.util.Arrays;
public class MaopaoSort {
static int[] array = {3,2,4,1,5,0};
public static void maopaoSort(int[] a)
{
//外层循环,是需要进行比较的轮数,一共进行5次即可
for(int i=0;i<a.length-1;i++)
{
//内存循环,是每一轮中进行的两两比较
for(int j=0;j<a.length-1;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"轮排序后的数组为: "+Arrays.toString(a));
}
}
public static void main(String[] args) {
maopaoSort(array);
}
}
输出结果
第1轮排序后的数组为: [2, 3, 1, 4, 0, 5]
第2轮排序后的数组为: [2, 1, 3, 0, 4, 5]
第3轮排序后的数组为: [1, 2, 0, 3, 4, 5]
第4轮排序后的数组为: [1, 0, 2, 3, 4, 5]
第5轮排序后的数组为: [0, 1, 2, 3, 4, 5]
冒泡排序的优化
1 .观察上述代码和运行结果,我们可以发现,当第一轮结束后,最后一个数字一定是数组中最大的元素,那么我们在进行第二趟的两两比较时,实际上是没有必要再对第5个和第6个进行比较的。那么我们可以修改代码如下:
public static void maopaoSort(int[] a)
{
//外层循环,是需要进行比较的轮数,一共进行5次即可
for(int i=0;i<a.length-1;i++)
{
//内存循环,是每一轮中进行的两两比较
//并且每一轮结束后,下一次的两两比较中可以少比较一次
for(int j=0;j<a.length-i-1;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"轮排序后的数组为: "+Arrays.toString(a));
}
}
继续运行后,可以发现运行结果是一样的。
2 .当我们用数组:{1,2,0,3,5,4}来测试上述冒泡排序时,运行结果如下:
第1轮排序后的数组为: [1, 0, 2, 3, 4, 5]
第2轮排序后的数组为: [0, 1, 2, 3, 4, 5]
第3轮排序后的数组为: [0, 1, 2, 3, 4, 5]
第4轮排序后的数组为: [0, 1, 2, 3, 4, 5]
第5轮排序后的数组为: [0, 1, 2, 3, 4, 5]
可以看到,在第2轮排序完成后,其实我们就已经的到了排好序的数组,但是我们的程序并不知道,仍然进行了后续的无用工作。那么,我们如何来让程序知道已经完成好排序了呢?
这里可以想到,当某一轮的两两比较中,如果都没有发生数组元素的互换,那么其实排序工作已经完成了,所以我们可以考虑在程序中加入一个flag,默认为false,含义是该轮比较中是否发生了元素互换,当程序中执行到元素互换时,将该flag置为true,当该轮比较结束时,若flag为flase,则说明该轮比较未发生元素互换,那么排序完成,若flag为true,说明本轮比较仍然有元素互换,需要继续进行下轮排序。代码实现如下:
/**
* @Author {LearnAndGet}
* @Time 2019年1月8日
* @Discription:
*/
package com.sort;
import java.util.Arrays;
public class MaopaoSort {
static int[] array = {1,2,0,3,5,4};
public static void maopaoSort(int[] a)
{
//外层循环,是需要进行比较的轮数,一共进行5次即可
for(int i=0;i<a.length-1;i++)
{
boolean flag = false;
//内存循环,是每一轮中进行的两两比较
for(int j=0;j<a.length-i-1;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
flag = true;
}
}
System.out.println("第"+(i+1)+"轮排序后的数组为: "+Arrays.toString(a));
if(flag == false)
{
System.out.println("本轮中的两两比较未发生元素互换,排序已经完成啦");
return;
}
}
}
public static void main(String[] args) {
maopaoSort(array);
}
}
运行结果:
第1轮排序后的数组为: [1, 0, 2, 3, 4, 5]
第2轮排序后的数组为: [0, 1, 2, 3, 4, 5]
第3轮排序后的数组为: [0, 1, 2, 3, 4, 5]
本轮中的两两比较未发生元素互换,排序已经完成啦
冒泡排序的时间复杂度
冒泡排序是一种用时间换空间的排序方法,最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。在这种情况下,每一次比较都需要进行交换运算。举个例子来说,一个数列 5 4 3 2 1 进行冒泡升序排列
第一轮的两两比较,需要比较4次;得到 4 3 2 1 5
第二轮的两两比较,需要比较3次;得到 3 2 1 4 5
第三轮的两两比较,需要比较2次;得到 2 1 3 4 5
第四轮的两两比较,需要比较1次;得到 1 2 3 4 5
所以总的比较次数为 4 + 3 + 2 + 1 = 10次
对于n位的数列则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数。
而O(N^2)表示的是复杂度的数量级。举个例子来说,如果n = 10000,那么 n(n-1)/2 = (n^2 - n) / 2 = (100000000 - 10000) / 2,相对10^8来说,10000小的可以忽略不计了,所以总计算次数约为0.5 * N2。用O(N2)就表示了其数量级(忽略前面系数0.5)。
综上所述,冒泡排序的时间复杂度为:O(n²)
java实现几种常用排序:冒泡排序的更多相关文章
- java实现几种常用排序:选择排序
一.选择排序介绍 选择排序,顾名思义就是用逐个选择的方式来进行排序,逐个选择出数组中的最大(或最小)的元素,直到选择至最后一个元素.此时数组完成了排序. 二.选择排序原理分析 三.选择排序代码实现 / ...
- java 中几种常用数据结构
Java中有几种常用的数据结构,主要分为Collection和map两个主要接口(接口只提供方法,并不提供实现),而程序中最终使用的数据结构是继承自这些接口的数据结构类. 一.几个常用类的区别 1.A ...
- Java中几种常用数据类型之间转换的方法
Java中几种常用的数据类型之间转换方法: 1. short-->int 转换 exp: short shortvar=0; int intvar=0; shortvar= (short) in ...
- 【知了堂学习笔记】java 编写几种常见排序算法
排序的分类: 一.交换排序 所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动. 1.冒泡 ...
- java正则表达式四种常用的处理方式是怎么样呢《匹配、分割、代替、获取》
java 正则表达式高级篇,介绍四种常用的处理方式:匹配.分割.替代.获取,具体内容如下package test; import java.util.regex.Matcher; import jav ...
- JAVA 正则表达式4种常用的功能
下面简单的说下它的4种常用功能: 查询: 以下是代码片段: String str="abc efg ABC"; String regEx="a|f" ...
- 用 Java 实现的八种常用排序算法
八种排序算法可以按照如图分类 交换排序 所谓交换,就是序列中任意两个元素进行比较,根据比较结果来交换各自在序列中的位置,以此达到排序的目的. 1. 冒泡排序 冒泡排序是一种简单的交换排序算法,以升序排 ...
- Java种八种常用排序算法
1 直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中. 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列. 对第四个数.第五个数……直 ...
- 转:Java实现几种常见排序方法
日常操作中常见的排序方法有:冒泡排序.快速排序.选择排序.插入排序.希尔排序,甚至还有基数排序.鸡尾酒排序.桶排序.鸽巢排序.归并排序等. 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一 ...
随机推荐
- CSS 使用calc()获取当前可视屏幕高度
来自:https://blog.csdn.net/qq_32063079/article/details/89766442 先了解一下CSS3的相对长度单位(参考详细教程) : 相对长度单位指定了一个 ...
- LINUX中lrzsz软件的使用
安装lrzsz 可以在Linux 和 windows直接相互传文件 Linux无论ssh跳过去也可以sz rz打开图像进行传输文件 [root@master2 ~]# yum install lrzs ...
- 中断或取消Promise链的可行方案
ES6标准引入的异步编程解决方案Promise,能够将层层嵌套的回调转化成扁平的Promise链式调用,优雅地解决了“回调地狱”的问题.当Promise链中抛出一个错误时,错误信息沿着链路向后传递,直 ...
- Cowrie蜜罐部署教程
0.蜜罐分类: 低交互:模拟服务和漏洞以便收集信息和恶意软件,但是攻击者无法和该系统进行交互: 中等交互:在一个特有的控制环境中模拟一个生产服务,允许攻击者的部分交互: 高交互:攻击者可以几乎自由 ...
- 超简单!教你如何修改源列表(sources.list)来提高软件访问速度
因为Ubuntu官方的源地址不在国内,所以在国内的访问速度非常慢,比如:我们要下载或是更新软件那速度比蜗牛还慢.所以,我们需要改成国内的镜像服务器,这样,我们在下载或更新软件的时候就会很快了. 配置步 ...
- Android异常与性能优化相关面试问题-冷启动优化面试问题详解
什么是冷启动: 冷启动的定义:冷启动就是在启动应用前,系统中没有该应用的任何进程信息.实际也就是要执行Application.onCreate()方法的那次启动. 冷启动 / 热启动的区别:热启动:用 ...
- URL编码以及GET和POST提交乱码解决方案 (转)
1. 什么是URL编码. URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服 ...
- MyBatis Demo
什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索.MyBat ...
- 创建表空间 ora-01119
create tablespace user_data logging datafile 'D:\app\Administrator\oradata\orcl\ARCHIVE.dbf' size 50 ...
- hadoop中的JournalNode
1.在HADOOP扮演的角色 JournalNode是在MR2也就是Yarn中新加的,journalNode的作用是存放EditLog的, 在MR1中editlog是和fsimage存放在一起的然后S ...