关于冒泡排序的Java代码实现
一.排序算法的历史:
排序算法的发展历史几乎和计算机的发展历史一样悠久,而且直到今天,世界范围内依然有计算机科学家正在研究着排序的算法,由此可见排序算法的强大魅力. 我们现在介绍的排序算法都是前任研究的经典成果,具有极高的学习价值和借鉴意义.
排序算法属于算法的一种,而且是覆盖范围极小的一种,虽然排序算法是计算机科学里古老而且研究人数相当多的一张算法,但千万不要把排序算法和广义的计算机算法等同起来,掌握排序算法对程序开发,程序思维的培养都有很大的帮助,但掌握排序算法绝不等于掌握了计算机编程算法的全部.广义的算法包括客观世界的运行规律.
二.排序的目的是查找 和 衡量排序算法的标准
一旦将一组杂乱无章的记录重排成一组有序记录,就能快速的从这组记录中找到目标记录.因此通常来说,排序的目的是快速查找.
对于一个排序算法来说,一般从个如下三个方面来衡量算法的优劣.
1.时间复杂度:主要是分析关键字的比较次数和记录的移动次数.
2.空间复杂度:分析排序算法中需要多少辅助内存.
3.稳定性:若两个记录A和B的关键值相等,但排序后A,B的先后次序保持不变,则称这种排序算法是稳定的,反之,就是不稳定的.
三.排序的分类(内部排序和外部排序)
就现有的排序算法来看,排序大致可以分为内部排序和外部排序.
1.外部排序
如果参与排序的数据元素非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘),这种排序就被称为外部排序.
外部排序最常用的算法是多路归并排序,即将源文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序,接下来再对多个有序的子文件进行归并排序.
(一)外部排序包括以下两个步骤:
1.把要排序的文件中的一组记录读入内存的排序区,对读入的记录按上面讲到的内部排序法进行排序,排序之后输出到外部存储器,不断的重复这个过程,每次读取一组记录,直到源文件的所有记录被处理完毕.
2.将上一步分组排序好的记录两组两组的合并排序,在内存容量允许的条件下,每组中包含的记录越大越好,这样可以减少合并的次数.
对于外部排序来说,程序必须将数据分批调入内存来排序,中间结果还要及时放入外存,显然外部排序要比内部排序更复杂,实际上,也可以认为外部排序是由多次内部排序组成的.常说的排序都是指的内部排序,而不是外部排序.
2.内部排序:
如果整个排序过程不需要借助外部存储器(如磁盘),这种排序就被称为内部排序.
(一) 内部排序的分类:
①选择排序(直接选择排序,堆排序)
②交换排序(冒泡排序,快速排序)
③插入排序(直接插入排序,折半插入排序,Shell排序)
④归并排序
⑤桶式排序
⑥基数排序
从图中可以看出,常见的内部排序大致可以分为6大类,具体有10种排序方法.
四.冒泡排序
(一)冒泡排序的过程
冒泡排序是最广为人知的交换排序之一,它具有算法思路简单,容易实现的特点.
对于包含n个数据的一组记录,在最坏的情况下,冒泡排序需要进行n-1趟比较.
第1趟:一次比较0和1,1和2,2和3....n-2和n-1索引处的元素,如果发现第一个数据大于后一个数据,则交换它们. 经过第1趟比较,最大的元素排到了最后.
第2趟:一次比较0和1,1和2,2和3....n-3和n-2索引处的元素, 如果发现第一个数据大于后一个数据,则交换它们. 经过第2趟比较,第2大的元素排到了倒数第2位.
........
第n-1趟:依次比较0和1元素,如果发现第一个数据大于后一个数据,则交换它们. 经过第n-1趟比较,第2小(第n-1大)的元素排到了第2位.
实际上,冒泡排序的每趟交换结束后,不仅能将当前最大值挤出最后面位置,还能部分理顺前面的其他元素,一旦某趟没有交换发生,即可提前结束排序.
(二) 冒泡排序具体举例:
假设有如下数据序列:
9,16,21*,23,30,49,21,30*
只需要经过如下几趟排序.
第1趟:9,16,21*,23,30,21,30*,49
第2趟:9,16,21*,23,21,30,30*,49
第3趟:9,16,21*,21,23,30,30*,49
第4趟:9,16,21*,21,23,30,30*,49
从上面的排序过程可以看出,虽然该数组包含8个元素,但是采用冒泡排序只需要经过4趟比较.因为第3趟排序之后,这组数据已经处于有序状态.这样,第4趟将不会发生交换,因此可以提前结束循环.
(三)冒泡排序的具体代码
冒泡排序的示例程序如下:
上代码:
package cn.summerchill.sort; // 定义一个数据包装类
class DataWrap implements Comparable<DataWrap> {
int data;
String flag; public DataWrap(int data, String flag) {
this.data = data;
this.flag = flag;
} public String toString() {
return data + flag;
} // 根据data实例变量来决定两个DataWrap的大小
public int compareTo(DataWrap dw) {
return this.data > dw.data ? 1 : (this.data == dw.data ? 0 : -1);
}
} public class BubbleSort {
public static void bubbleSort(DataWrap[] data) {
System.out.println("开始排序");
int arrayLength = data.length;
for (int i = 0; i < arrayLength - 1; i++) {
boolean flag = false;
for (int j = 0; j < arrayLength - 1 - i; j++) {
// 如果j索引处的元素大于j+1索引处的元素
if (data[j].compareTo(data[j + 1]) > 0) {
// 交换它们
DataWrap tmp = data[j + 1];
data[j + 1] = data[j];
data[j] = tmp;
flag = true;
}
}
System.out.println(java.util.Arrays.toString(data));
// 如果某趟没有发生交换,则表明已处于有序状态
if (!flag) {
break;
}
}
} public static void main(String[] args) {
DataWrap[] data = { new DataWrap(9, ""), new DataWrap(16, ""),
new DataWrap(21, "*"), new DataWrap(23, ""),
new DataWrap(30, ""), new DataWrap(49, ""),
new DataWrap(21, ""), new DataWrap(30, "*") };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
bubbleSort(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}
运行上面的程序,将看到如图所示的排序过程.
排序之前:
[9, 16, 21*, 23, 30, 49, 21, 30*]
开始排序
[9, 16, 21*, 23, 30, 21, 30*, 49]
[9, 16, 21*, 23, 21, 30, 30*, 49]
[9, 16, 21*, 21, 23, 30, 30*, 49]
[9, 16, 21*, 21, 23, 30, 30*, 49]
排序之后:
[9, 16, 21*, 21, 23, 30, 30*, 49]
冒泡排序算法的时间效率是不确定的.在最好的情况下,初始数据序列已经处于有序状态,执行1趟冒泡即可,做n-1次比较.无须进行任何交换.
但在最坏的情况下,初始数据序列处于完全逆序状态,算法要执行n-1趟冒泡,第i趟(1<i<n)做了n-i次比较,执行n-i-1次对象交换. 此时的比较总次数为n*(n-1)/2,记录移动总次数为n*(n-1)*3/2.
冒泡排序算法的空间效率很高,它只需要一个附加程序单元用于交换,其空间效率为O(1). 冒泡排序是稳定的.
=============================================================
另外一种方式:
public class BubbleSort {
public static void main(String[] args) {
Integer arr[] = { 2, 4, 1, 3, 9, 5, 8};
bubbleSort(arr);
}
public static Integer[] bubbleSort(Integer[] arr){
if(arr != null && arr.length > 0){
//n个数字,冒泡排序需要n-1趟
for(int i = 0; i < arr.length -1; i++ ){
//在每一趟内部进行交换排序 n个数字,需要n-1次两两比较
for(int j = 0; j < arr.length -1; j++){
int temp;
if(arr[j + 1] < arr[j]){
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
System.out.println("第" + i +"趟排序之后的数组内顺序为:" );
for (int k = 0 ; k < arr.length; k++){
System.out.print( arr[k] + " ");
}
System.out.println();
}
}
return null;
}
}
关于冒泡排序的Java代码实现的更多相关文章
- 常见的排序算法之Java代码解释
一 简要介绍 一般排序均值的是将一个已经无序的序列数据重新排列成有序的 常见的排序分为: 1 插入类排序 主要就是对于一个已经有序的序列中,插入一个新的记录.它包括:直接插入排序,折半插入排序和希尔排 ...
- java 代码
java 里的 pandas tablesaw DataFrame 再有就是 spark 了 java 代码规范 Java8特性详解 lambda表达式 Stream Sonar 规则检测 sprin ...
- 专题 查找与排序的Java代码实现(一)
专题 查找与排序的Java代码实现(一) 查找(Searching) 线性查找(linear search) 属于无序查找算法,适合于存储结构为顺序存储或链接存储的线性表. 基本思想:从数据结构线形表 ...
- 十大经典排序算法最强总结(含JAVA代码实现)(转)
十大经典排序算法最强总结(含JAVA代码实现) 最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每 ...
- 第二章:排序算法 及其他 Java代码实现
目录 第二章:排序算法 及其他 Java代码实现 插入排序 归并排序 选择排序算法 冒泡排序 查找算法 习题 2.3.7 第二章:排序算法 及其他 Java代码实现 --算法导论(Introducti ...
- 对一致性Hash算法,Java代码实现的深入研究
一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...
- 怎样编写高质量的java代码
代码质量概述 怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍.也请有过代码质量相关经验的朋友 ...
- 数据结构笔记--二叉查找树概述以及java代码实现
一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...
- java代码的初始化过程研究
刚刚在ITeye上看到一篇关于java代码初始化的文章,看到代码我试着推理了下结果,虽然是大学时代学的知识了,没想到还能做对.(看来自己大学时掌握的基础还算不错,(*^__^*) 嘻嘻……)但 ...
随机推荐
- [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]
Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...
- Netty学习第六节实例一步学习
NIO与传统IO对应使用的类: ServerSocketChannel相当于ServerSocket SocketChannel 相当于Socket Selector是NIO的核心类,是负责监听Ser ...
- mysql 经典错误解决方案 :Incorrect string value 'xE6x95x85xE4xBAx8B...' for column
1.关闭当前服务器2.删除正在使用的数据库drop database 数据库名字;3.查看字符集, SHOW VARIABLES LIKE 'character_set_%'; 把所有latin1的都 ...
- @WebService @WebMethod 详解
形象图解 首先AB均需要@WebService如果 @WebService(endpointInterface="package.B") public class A implem ...
- Bezier曲线
1. 学习网址 http://give.zju.edu.cn/cgcourse/new/book/8.2.htm
- java web 入门实例servlet篇(显示后台数据库列表,删除某一条记录并显示)
编写过程中需要注意的问题: 1.建立eclipse动态web工程时,需要改写编译后class文件的位置,通常情况下是这个位置:/WebContent/WEB-INF/classes 2.配置的页面链接 ...
- Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项
http://blog.csdn.net/delphiteacher/article/details/8924110 Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox ...
- unlimited channel buffer in Go
channel buffer可以事先分配大小,但是这些是需要占用内存的,事先分配几G内存给一个channel很浪费资源的,所以怎样创建一个无限的channel buffer呢?比较naive的写法就是 ...
- 轻松转移github项目步骤
之前有一些项目是托管在github上的,无奈github速度太慢,而且空间有限,还不能有私有项目.后来发现开源中国的git托管(git.oschina.net)还不错,可以托管1000个项目,而且可以 ...
- TFS 2015 生成不输出任何结果
这是一台用于测试的TFS 2015服务器,其中的数据是通过备份和还原,在使用应用层专用的方式配置出来的. 在配置完成代理服务器以后,运行生成,发现在获取代码之前就停止失败了,并且在生成过程中没有任何结 ...