排序原理:

1. 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置。

2. 对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值。

**初始状态到第一次冒泡 : **

  1. 比较 4,5,5比4大,不变。
  2. 比较5,6,6比5大,不变
  3. 比较6,3,3比6小,交换二者位置 4,5,3,6,2,1
  4. 比较6,2,2比6小,交换二者位置 4,5,3,2,6,1
  5. 比较6,1,1比6小,交换二者位置 4,5,3,2,1,6

假设数组长度为n,冒泡排序必须实现n-1次冒泡(令k = n)

第一次冒泡要有k-1次比较

第二次冒泡要有k-2次比较

第n-1次冒泡要有k-n-1次比较

1
2
3
4
5
6
7
8
9
public static void sort(Comparable[] a){
for (int i = a.length-1;i > 0;i--){
for (int j = 0; j < i; j++) {
if (greater(a[j],a[j+1])){
exch(a,j,j+1);
}
}
}
}

使用两个for循环进行遍历,第一个for循环表示冒泡的次数为:数组长度-1

第二个for循环表示相邻数组元素依次比较,j < i 表示排序完的元素放在数组的后面,不需要再次进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package SORT;
/**
* @author Hzy
* @create 2022/1/14
* 10:59
*/
// 1.public static void sort(Comparable[] a):对数组内的元素进行排序
// 2.private static boolean greater(Comparable v,Comparable w):判断v是否大于w
// 3.private static void exch(Comparable[] a,int i,int j):交换a数组中,索引i和索引j处的值

public class Bubble {

//对数组内的元素进行排序
public static void sort(Comparable[] a){
for (int i = a.length-1;i > 0;i--){
for (int j = 0; j < i; j++) {
if (greater(a[j],a[j+1])){
exch(a,j,j+1);
}
}
}
}

//判断v是否大于w
private static boolean greater(Comparable v,Comparable w){
int result = v.compareTo(w);
if (result>0) {
return true;
} else {
return false;
}
// return result>0;
}

//交换a数组中,索引i和索引j处的值
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}

冒泡排序的时间复杂度分析 冒泡排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码

**所以, 分析冒泡排序的时间复杂度,主要分析一下内层循环体的执行次数即可。 **

在最坏情况下,也就是假如要排序的元素为{6,5,4,3,2,1}逆序,

那么: 元素比较的次数为: (N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

元素交换的次数为: (N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

总执行次数为: (N^2/2-N/2)+(N^2/2-N/2)=N^2-N;

按照大O推导法则,保留函数中的最高阶项那么最终冒泡排序的时间复杂度为O(N^2)