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);
}
}
上面代码运行结果:

@[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排序算法总结 从这三组时间复杂度对比中,可以看出,堆排序和归并排序是不管在什么情况下发挥稳定的,快速排序好的时候表现如天才,坏情况下比较差强人意,甚至在等待排序个数 ...
随机推荐
- coding++:Linux - Shell - 常用命令
1.在多个文件中 查找内容 find . -type f -name "*.html" | xargs grep "1"
- c++中的多态机制
目录 1 背景介绍 2 多态介绍 2-1 什么是多态 2-2 多态的分类 2-3 动态多态成立的条件 2-4 静态联编和动态联编 2-5 动态多态的实现原理 2-6 虚析构函数 ...
- LeetCode(一) jump game
一. 1. #include<iostream> #include<cmath> using namespace std; bool CanJump(int n[],int n ...
- springboot集成通用mapper详细配置
通常,我们利用mybatis写持久层方法.要么按照传统定义mapper方法,定义xml文件的方式,全部手写.要么需要通过mybatis-generator逆向工程插件生成大量的xxxExample文件 ...
- 2019NYIST计科第四次周赛
YZJ的牛肉干 Description 今年的ACM暑期集训队一共有18人,分为6支队伍.其中有一个叫做 YZJ的大佬,在共同的集训生活中,大家建立了深厚的友谊, YZJ准备做点什么来纪念这段激情燃烧 ...
- 深浅clone
原型模式 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 原型模式是基于深复制和浅复制的,在Java里面有2种复制: 浅复制将一个对象复制之后,生成一个新的对象,新对象的所有成员变量( ...
- PTA数据结构与算法题目集(中文) 7-29
PTA数据结构与算法题目集(中文) 7-29 7-29 修理牧场 (25 分) 农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条 ...
- modelform+代码发布系统前奏
目录 注意点 form.html 添加编辑页面 ModelForm 添加 编辑 删除 代码优化 优化1 优化2 优化3 注意点 <form class="form-horizontal ...
- 35 编码 ASCII Unicode UTF-8 ,字符串的编码、io流的编码
* 编码表: * 信息在计算机上是用二进制表示的,这种表示法让人理解就很困难.为保证人类和设备,设备和计算机之间能进行正确的信息交换,人们编制的统一的信息交换代码,这就是ASCII码表 *ASCII ...
- String 对象-->split() 方法
1.定义和用法 split() 方法用于把一个字符串分割成字符串数组. 语法: string.split(separator,limit) 参数: separator:可选.字符串或正则表达式,从该参 ...