关于冒泡排序的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趟将不会发生交换,因此可以提前结束循环.

(三)冒泡排序的具体代码

冒泡排序的示例程序如下:

上代码:

复制代码
 1 package cn.summerchill.sort;
 2 
 3 // 定义一个数据包装类
 4 class DataWrap implements Comparable<DataWrap> {
 5     int data;
 6     String flag;
 7 
 8     public DataWrap(int data, String flag) {
 9         this.data = data;
10         this.flag = flag;
11     }
12 
13     public String toString() {
14         return data + flag;
15     }
16 
17     // 根据data实例变量来决定两个DataWrap的大小
18     public int compareTo(DataWrap dw) {
19         return this.data > dw.data ? 1 : (this.data == dw.data ? 0 : -1);
20     }
21 }
22 
23 public class BubbleSort {
24     public static void bubbleSort(DataWrap[] data) {
25         System.out.println("开始排序");
26         int arrayLength = data.length;
27         for (int i = 0; i < arrayLength - 1; i++) {
28             boolean flag = false;
29             for (int j = 0; j < arrayLength - 1 - i; j++) {
30                 // 如果j索引处的元素大于j+1索引处的元素
31                 if (data[j].compareTo(data[j + 1]) > 0) {
32                     // 交换它们
33                     DataWrap tmp = data[j + 1];
34                     data[j + 1] = data[j];
35                     data[j] = tmp;
36                     flag = true;
37                 }
38             }
39             System.out.println(java.util.Arrays.toString(data));
40             // 如果某趟没有发生交换,则表明已处于有序状态
41             if (!flag) {
42                 break;
43             }
44         }
45     }
46 
47     public static void main(String[] args) {
48         DataWrap[] data = { new DataWrap(9, ""), new DataWrap(16, ""),
49                             new DataWrap(21, "*"), new DataWrap(23, ""),
50                             new DataWrap(30, ""), new DataWrap(49, ""), 
51                             new DataWrap(21, ""), new DataWrap(30, "*") };
52         System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
53         bubbleSort(data);
54         System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
55     }
56 }
复制代码

运行上面的程序,将看到如图所示的排序过程.

复制代码
排序之前:
[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).     冒泡排序是稳定的.

=============================================================

另外一种方式:

复制代码
 1 public class BubbleSort {
 2     public static void main(String[] args) {
 3         Integer arr[] = { 2, 4, 1, 3, 9, 5, 8};
 4         bubbleSort(arr);
 5     }
 6     public static Integer[] bubbleSort(Integer[] arr){
 7         if(arr != null && arr.length > 0){
 8             //n个数字,冒泡排序需要n-1趟
 9             for(int i = 0; i < arr.length -1; i++ ){
10                 //在每一趟内部进行交换排序 n个数字,需要n-1次两两比较
11                 for(int j = 0; j < arr.length -1; j++){
12                     int temp;
13                     if(arr[j + 1] < arr[j]){
14                         temp = arr[j + 1];
15                         arr[j + 1] = arr[j];
16                         arr[j] = temp;
17                     }
18                 }
19                 System.out.println("第" + i +"趟排序之后的数组内顺序为:" );
20                 for (int k = 0 ; k < arr.length; k++){
21                     System.out.print( arr[k] + " ");
22                 }
23                 System.out.println();
24             }
25         }
26         return null;
27     }
28 }
复制代码

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/4083839.html,如需转载请自行联系原作者

相关文章
|
20小时前
|
Java 数据处理 开发者
Java中的Lambda表达式:简化你的代码之路
【8月更文挑战第66天】Lambda表达式在Java 8中首次引入,它为Java开发者提供了一种更简洁、更灵活的编程方式。本文将通过简单易懂的语言和实际代码示例,引导你理解Lambda表达式的基本概念、语法结构以及如何在Java项目中应用它来简化代码。无论你是Java新手还是有经验的开发者,这篇文章都将帮助你更好地掌握这一强大的工具。
28 11
|
18天前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
7天前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
20 5
|
9天前
|
Java API 开发者
探索Java中的Lambda表达式:简洁与强大的代码实践
本文深入探讨Java中Lambda表达式的定义、用法及优势,通过实例展示其如何简化代码、提升可读性,并强调在使用中需注意的兼容性和效率问题。Lambda作为Java 8的亮点功能,不仅优化了集合操作,还促进了函数式编程范式的应用,为开发者提供了更灵活的编码方式。
|
5天前
|
Java 开发者
探索Java中的Lambda表达式:简化你的代码之旅##
【8月更文挑战第62天】 Java 8的发布为开发者带来了诸多新特性,其中最引人注目的无疑是Lambda表达式。这一特性不仅让代码变得更加简洁,还极大地提升了开发的效率。本文将通过实际示例,展示如何利用Lambda表达式来优化我们的代码结构,同时探讨其背后的工作原理和性能考量。 ##
|
8天前
|
Java API 开发者
探索Java中的Lambda表达式:简化代码,提升效率
【9月更文挑战第27天】在Java 8中引入的Lambda表达式为编程带来了革命性的变化。通过简洁的语法和强大的功能,它不仅简化了代码编写过程,还显著提升了程序的执行效率。本文将深入探讨Lambda表达式的本质、用法和优势,并结合实例演示其在实际开发中的应用。无论你是Java新手还是资深开发者,都能从中获得启发,优化你的代码设计。
|
9天前
|
Java Linux Python
Linux环境下 代码java调用python出错
Linux环境下 代码java调用python出错
24 3
|
8天前
|
存储 Java 索引
使用java代码实现左右括号查找
使用java代码实现左右括号查找
|
9天前
|
算法 Java
java 概率抽奖代码实现
java 概率抽奖代码实现
|
18天前
|
Java 程序员 API
Java中的Lambda表达式:简化代码的秘密武器
在Java 8中引入的Lambda表达式是一种强大的编程工具,它可以显著简化代码,提高可读性。本文将介绍Lambda表达式的基本概念、优势以及在实际开发中的应用。通过具体示例,您将了解如何使用Lambda表达式来简化集合操作、线程编程和函数式编程。让我们一起探索这一革命性的特性,看看它是如何改变Java编程方式的。
25 4
下一篇
无影云桌面