冒泡排序

基本冒泡排序

冒泡排序是一种非常易于了解的排序,它和我们小学时候站队是一样的道理:从第一个人开始,每次只和他右边的人相比较,如果第一个人比第二个人高,那么交换这两人的位置。否则,则从第二个人开始,继续如此往下,直到最后一个人。每趟下来,排在最右边的就是最高的。如果有n个人,那么执行n-1趟,整个队伍就是有序的。
为了方便理解,我们用图形来演示,原始的队伍是:

第一趟排序的过程:
1号和2号相比,1号发现自己比2号矮,无需交换,接下来,从2号开始;
2号和3号相比,2号发现自己比3号矮,同样无需交换,接下来,从3号开始;
3号和4号相比,3号发现自己比4号高,那么3号和4号交换位置

这样第一躺排序的过程就完成了,如下:
这里写图片描述

接下来我们继续来看第二趟排序的过程:
1号和2号相比,1号发现自己比2号矮,无需交换,接下来,从2号开始;
2号和3号相比,2号发现自己比3号高,那么2号和3号交换位置
因为在第一趟排序中,已经确定了4号是最高的,因此3号无需和4号比较了

第二趟排序完成后如下:
这里写图片描述

经过前两趟排序之后,3号和4号已经排好序了。

下面我们继续第三躺排序的过程:
1号和2号相比,1号发现自己比2号矮,无需交换。
同样因为在第二躺排序中,已经确定3号是次高的了,因此2号无需和3号比较了。

到此,整个排序过程已经完成
这里写图片描述

现在我们来抽象一下上述过程:

对于有n个孩纸的排队,需要执行n-1趟排队过程
每次趟排队过程中都会确定此趟排序中最高的,例如,1号,2号,3号,4号中确定4号;1号,2号,3号中确定3号

我们用代码来描述冒泡排序:

public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {16, 4, 2, 5, 4, 63, 66, 32};
        sort3(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    public static void sort(int[] arr) {
        int n = arr.length;
        //对n个元素排序,只需要执行n-1趟
        for (int i = 0; i < n - 1; i++) {
            //每趟排序都会确定此趟中最高的,上一趟确定的最高的无须参与此趟排序
            for (int j = 1; j < n - i; j++) {
                if (arr[j - 1] > arr[j]) {
                    swap(arr, j - 1, j);
                }
            }
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

  • 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

冒泡排序的优化

现在我们再来看另外一种情况,如果队伍是这样的呢:
这里写图片描述

在经过第一趟排序之后:
这里写图片描述
这时你发现整个队伍已经是有序的了,按照上文的代码,你还是要进行第二趟,第三趟,第四趟比较的过程,而实际上这些过程完全是没有必要的。那可不可以优化呢?
现在我们来想一下冒泡排序的两种基本操作:比较和交换。在一个已经排序好的队伍中,仍然有比较操作,但是一定不会有交换操作。想到这里,我们的思路也就有了:

如果在某躺排序中没有发生交换操作,那说明整个队伍已经是有序的了。

因此,我们通过添加额外的一个标志位isSwap判断是否发生了交换,优化后的代码如下:

   public static void sort(int[] arr) {
        int n = arr.length;
        boolean isSwap = true;
        while (isSwap) {
            isSwap = false;
            for (int i = 0; i < n - 1; i++) {
                for (int j = 1; j < n - i; j++) {
                    if (arr[j - 1] > arr[j]) {
                        swap(arr, j - 1, j);
                        isSwap = true;
                    }

                }
            }
        }

    }

--------------------- 本文来自 江湖人称小白哥 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/dd864140130/article/details/50854359?utm_source=copy

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值