Java 排序算法-冒泡排序及其优化
什么是冒泡排序
这里引用一下百度百科上的定义:
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
冒泡排序在实际工作中用的并不多,多是面试题中会遇到。
下面用java代码来实现:
基本写法
为了看到后面优化后的效果,我加了count 和 num l两个变量来分布统计外循环和内循环的次数
/**
* 原始的冒泡排序
* @param values
*/
public static void bubbleSort(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp;// 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
for (int j = 0; j < values.length - 1; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
}
num ++;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
优化后写法
/**
* 优化了比较次数的冒泡排序
* @param values
*/
public static void bubbleSort2(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp; // 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
/* 每一趟循环都可以找你最大的数,内循环可以比上一趟循环减少一次比较 */
for (int j = 0; j < values.length - 1 - i; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
}
num ++;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
显然,每一趟循环都可以找你最大的数,内循环可以比上一趟循环减少一次,面试时写成这样基本OK了。
终极版本
实际中,用来比较的数据,可能就只有几个位置是无序的,如果也按照上面的写法进行 length -1 次循环就显得有点死板了。
因此我们可以假设数组已经排好序了,给程序一个标记变量,如果标记变量显示数组已排好序,则可以跳出循环。
/**
* 冒泡排序终极写法
* @param values
*/
public static void bubbleSort3(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp;// 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
// 定义一个boolean 值,标记数组是否达到有序状态
boolean flag = true;
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
/* 每一趟循环都可以找你最大的数,内循环可以比上一趟循环减少一次比较 */
for (int j = 0; j < values.length - 1 - i; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
// 如果本趟发生了交换,表明数组还是无序,需要进入下一轮循环
flag = false;
}
num ++;
}
// 根据标记的布尔值判断数组是否达到有序状态,如有序,则退出循环
if( flag) {
break;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
源码及测试
package com.xzlf.sort;
import java.util.Arrays;
public class TestSort {
public static void main(String[] args) {
int[] arr = {1,341,33,22,88,99,100};
int[] arr2 = {1,341,33,22,88,99,100};
int[] arr3 = {1,341,33,22,88,99,100};
bubbleSort(arr);
System.out.println("==================");
bubbleSort2(arr2);
System.out.println("==================");
bubbleSort3(arr3);
}
/**
* 原始的冒泡排序
* @param values
*/
public static void bubbleSort(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp;// 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
for (int j = 0; j < values.length - 1; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
}
num ++;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
/**
* 优化了比较次数的冒泡排序
* @param values
*/
public static void bubbleSort2(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp; // 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
/* 每一趟循环都可以找你最大的数,内循环可以比上一趟循环减少一次比较 */
for (int j = 0; j < values.length - 1 - i; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
}
num ++;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
/**
* 冒泡排序终极写法
* @param values
*/
public static void bubbleSort3(int[] values) {
System.out.println("排序前:" + Arrays.toString(values));
int tmp;// 循环外创建变量,减少垃圾产生,提高性能
int count = 0;// 比较了多少趟
int num = 0; // 比较次数
// 外层循环,n 个元素,最多需要 n -1 趟循环
for(int i = 0; i < values.length -1 ; i++) {
// 定义一个boolean 值,标记数组是否达到有序状态
boolean flag = true;
count ++;
// 内层循环, 每一次都从开始两个元素开始两两比较到最后
/* 每一趟循环都可以找你最大的数,内循环可以比上一趟循环减少一次比较 */
for (int j = 0; j < values.length - 1 - i; j++) {
if(values[j] > values[j + 1]) {
tmp = values[j];
values[j] = values[j + 1];
values[j + 1] = tmp;
// 如果本趟发生了交换,表明数组还是无序,需要进入下一轮循环
flag = false;
}
num ++;
}
// 根据标记的布尔值判断数组是否达到有序状态,如有序,则退出循环
if( flag) {
break;
}
}
System.out.println("排序后:" + Arrays.toString(values));
System.out.println("比较趟数:"+count + ",比较次数:" + num);
}
}
上面代码运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200315005725387.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5ODI3MDMz,size_16,color_FFFFFF,t_70)
@[TOC](Java/java基础)
Java 排序算法-冒泡排序及其优化的更多相关文章
- Java排序算法——冒泡排序
import java.util.Arrays; //================================================= // File Name : Bubble_S ...
- 常用Java排序算法
常用Java排序算法 冒泡排序 .选择排序.快速排序 package com.javaee.corejava; public class DataSort { public DataSort() { ...
- java排序算法(四):冒泡排序
java排序算法(四):冒泡排序 冒泡排序是计算机的一种排序方法,它的时间复杂度是o(n^2),虽然不及堆排序.快速排序o(nlogn,底数为2).但是有两个优点 1.编程复杂度很低.很容易写出代码 ...
- java排序算法之冒泡排序(Bubble Sort)
java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...
- java排序算法之冒泡排序和快速排序
总结一下Java排序算法,以便记忆. 各类排序的时间复杂度: 排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性 直接插入排序 O(n2)O(n2) O( ...
- java排序算法(一):概述
java排序算法(一)概述 排序是程序开发中一种非常常见的操作,对一组任意的数据元素(活记录)经过排序操作后,就可以把它们变成一组按关键字排序的一组有序序列 对一个排序的算法来说,一般从下面三个方面来 ...
- java排序算法(六):直接插入排序
java排序算法(六):直接插入排序 直接插入排序的基本操作就是将待的数据元素按其关键字的大小插入到前面的有序序列中 直接插入排序时间效率并不高,如果在最坏的情况下,所有元素的比较次数的总和为(0+1 ...
- Java排序算法之快速排序
Java排序算法之快速排序 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分 ...
- Java排序算法(三)
Java排序算法(三) 三.Java排序算法总结 从这三组时间复杂度对比中,可以看出,堆排序和归并排序是不管在什么情况下发挥稳定的,快速排序好的时候表现如天才,坏情况下比较差强人意,甚至在等待排序个数 ...
随机推荐
- arcgis10.4.X的oracle数据库要求
受支持的数据库版本:(标准版/标准独立版/企业版) Oracle 11g R2(64 位)11.2.0.4 Oracle 12c R1(64 位)12.1.0.2 受支持的操作系统: 数据库 支持的操 ...
- 9.Maven的生命周期
Clean Lifecycle: 在进行真正的构建之前进行一些清理工作. Default Lifecycle :构建的核心部分,编译,测试,打包,部署等等. Site Lifecycle : 生成项目 ...
- 读者来信 | 设置HBase TTL必须先disable表吗?(已解决)
今日有朋友加好友与我探讨一些问题,我觉得这些问题倒挺有价值的:于是就想在本公众号开设一个问答专栏,方便技术交流与分享,专栏名就定为:<读者来信>.如遇到本人能力有限难以解决的问题,该贴将会 ...
- Celery动态添加定时任务
背景 业务需求:用户可创建多个多人任务,需要在任务截止时间前一天提醒所有参与者 技术选型: Celery:分布式任务队列.实现异步与定时 django-celery-beat:实现动态添加定时任务,即 ...
- C++中的字符串切片操作
string str = "hello"; str.substr(0,2); //输出"he", 表示[0,2)
- thinkphp后端开发ajax接口开发测试
数据自动填充,Firefox的网络查看JSON数据,查错. 同时,用getLastSql函数查询,并且开启日志文件记录网页执行的全过程,还可以用thinkPHP内置的trace的跟踪. 谁有更好地方法 ...
- UC接口文档
UC接口文档 一.功能描述 提供同步登录.退出.注册等相关接口,可以实现用户一个账号,在一处登录,全站通行. 二.测试环境UC地址 http://s1.p5w.net/uc/ 三.相关接口 UC_AP ...
- Go golang语言特性
一.垃圾回收 1.内存自动回收. 2.只需要创建,不需要释放 二.天然并发: 1.语言层支持并发,对比python,少了GIL锁. 2.goroute,轻量级线程. 3.基于CSP模型实现 三.cha ...
- shell脚本编程(ubantu)
项目 内容 这个作业属于那个课程 这里是链接 作业要求在哪里 这里是链接 学号-姓名 17041506-张政 作业学习目标 了解shell脚本的概念及使用:掌握shell脚本语言的基本语法:学习简单的 ...
- python3(二十二) oop
""" 面向对象编程 """ __author__ = 'shaozhiqi' # 面向对象的程序设计把计算机程序视为一组对象的集合,而每个 ...