[排序算法]--冒泡排序的三种实现(Java)

本文详细介绍了冒泡排序的基本原理及其实现,并通过三种不同的Java实现方式展示了如何逐步优化冒泡排序算法,以提高其在特定场景下的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[排序算法]–冒泡排序的三种实现(Java)
2018年03月09日 11:03:13 蜗牛背壳爬葡萄树 阅读数:3697
设数组的长度为N:
(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。

(2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。

(3)N=N-1,如果N不为0就重复前面二步,否则排序完成。

以上就是冒泡排序的基本思想,按照这个定义很快就能写出代码:

/**

  • 冒泡排序的第一种实现, 没有任何优化

  • @param a

  • @param n
    */
    public static void bubbleSort1(int [] a, int n){
    int i, j;

    for(i=0; i<n; i++){//表示n次排序过程。
    for(j=1; j<n-i; j++){
    if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换
    //交换a[j-1]和a[j]
    int temp;
    temp = a[j-1];
    a[j-1] = a[j];
    a[j]=temp;
    }
    }
    }
    }// end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    给出一个测试代码:

public static void main(String[] args) {
int[] arr = {1,1,2,0,9,3,12,7,8,3,4,65,22};

BubbleSort.bubbleSort1(arr, arr.length);

for(int i:arr){
    System.out.print(i+",");
}

}
1
2
3
4
5
6
7
8
9
运行结果:

0,1,1,2,3,3,4,7,8,9,12,22,65,
1
下面开始考虑优化,如果对于一个本身有序的序列,或则序列后面一大部分都是有序的序列,上面的算法就会浪费很多的时间开销,这里设置一个标志flag,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。

/**

  • 设置一个标志,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。

  • @param a

  • @param n
    */
    public static void bubbleSort2(int [] a, int n){
    int j, k = n;
    boolean flag = true;//发生了交换就为true, 没发生就为false,第一次判断时必须标志位true。
    while (flag){
    flag=false;//每次开始排序前,都设置flag为未排序过
    for(j=1; j<k; j++){
    if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换
    //交换a[j-1]和a[j]
    int temp;
    temp = a[j-1];
    a[j-1] = a[j];
    a[j]=temp;

             //表示交换过数据;
             flag = true;
         }
     }
     k--;//减小一次排序的尾边界
    

    }//end while
    }//end
    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
    运行测试main函数结果:

0,1,1,2,3,3,4,7,8,9,12,22,65,
1
再进一步做优化。比如,现在有一个包含1000个数的数组,仅前面100个无序,后面900个都已排好序且都大于前面100个数字,那么在第一趟遍历后,最后发生交换的位置必定小于100,且这个位置之后的数据必定已经有序了,也就是这个位置以后的数据不需要再排序了,于是记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。如果是对于上面的冒泡排序算法2来说,虽然也只排序100次,但是前面的100次排序每次都要对后面的900个数据进行比较,而对于现在的排序算法3,只需要有一次比较后面的900个数据,之后就会设置尾边界,保证后面的900个数据不再被排序。

public static void bubbleSort3(int [] a, int n){
int j , k;
int flag = n ;//flag来记录最后交换的位置,也就是排序的尾边界

while (flag > 0){//排序未结束标志
    k = flag; //k 来记录遍历的尾边界
    flag = 0;

    for(j=1; j<k; j++){
        if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换
            //交换a[j-1]和a[j]
            int temp;
            temp = a[j-1];
            a[j-1] = a[j];
            a[j]=temp;

            //表示交换过数据;
            flag = j;//记录最新的尾边界.
        }
    }
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
这种方法是我看到的最优化的冒泡排序了。
运行测试例子结果:

0,1,1,2,3,3,4,7,8,9,12,22,65,
1
可知运行结果正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值