Java中的冒泡排序---傻瓜版

一、什么是冒泡排序

        冒泡排序(BubbleSort),顾名思义,由于整个排序的过程重复进行多次比较交换元素位置的操作,就好像水中气泡上浮的状态,故得名。冒泡排序的整个过程分为多轮,每轮又分为多次(轮次数由需要排序的元素个数决定),以升序为例,每一轮冒泡都是从第1个元素开始,依次比较1&2,2&3,3&4,4&5……如果在比较的过程中发现前一个元素大于后一个元素,则将二者位置调换,因此可以实现每一轮冒泡,都能将该轮所有元素中的最大元素排到该轮所有元素末尾。这样经过多轮冒泡,就能保证所有元素的顺序排列。

二、冒泡排序的排序过程

        以升序规则(最终实现从小到大排列)为例,我们看一下冒泡的具体实现过程:

        可以看到第一轮排序经过5次比较+交换位置的操作,最终实现了将所有元素中最大的元素排到了倒数第一个位置。 

         由于第一轮已经将最大元素9找到并放在了最后的位置,所以第二轮9这个元素不再参加比较;第二轮排序经过4次比较+交换位置的操作,最终实现了将所有元素中第二大的元素排到了倒数第二个位置

        同上,本轮元素7和元素9不再参加比较; 第三轮排序经过3次比较+交换位置的操作,最终实现了将所有元素中第三大的元素排到了倒数第三个位置

        由于数组实例的特殊性其实我们发现第三轮排序过后,升序排列的需求已经实现了,但为了演示冒泡排序的全过程,这里先不省略后续步骤。

         第四轮排序经过2次比较+交换位置的操作,最终实现了将所有元素中第四大的元素排到了倒数第四个位置

         第五轮排序经过1次比较+交换位置的操作,最终实现了将所有元素中第五大的元素排到了倒数第五个位置

        由于数组共有6个元素,我们已经按顺序定位好了其中5个,因此最小的元素位置也得以确定,冒泡排序到此结束。

三、代码实现

        可以看到排序过程有多轮多次,因此这里我们使用双层循环来实现,具体如下:

public class BubbleSortDemo {
    public static void main(String[] args) {
        int[] nums = {6, 2, 9, 5, 3, 7};
        System.out.println("排序前原始数组: " + Arrays.toString(nums));
        bubbleSort(nums);
        System.out.println("排序后的数组: " + Arrays.toString(nums));
    }

    private static void bubbleSort(int[] arr) {

        /*  
            外层循环,对应轮数;以本例而言数组共6个元素,进行五轮冒泡之后
            已经从大到小从后到前确定了5个元素的位置,最后一个元素也就不用在冒泡了,
            必然在第一个位置,所以这里的循环终止条件为i < arr.length - 1
        */
        for (int i = 0; i < arr.length - 1; i++) {

            /*内层循环,对应每轮的次数,应逐轮递减(arr.length - 1- i)*/
            for (int j = 0; j < arr.length - 1- i; j++) {
                
                //比较交换
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];//定义临时中间变量用于两个位置的值交换
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

运行结果如下:

         至此,冒泡排序的整个流程我们已经了解,但是上述过程中仍然存在问题;比如每一轮冒泡的过程,可能不止移动了当前轮最大的元素,其中较大的元素也可能在向后移动位置,又比如由于原始数组的不确定性,冒泡排序不一定要经过(元素数-1)轮才能完成排序,提前完成排序又会导致后面的循环轮次在do nothing,因此我们来通过优化代码解决一下这个问题:

        思路:冒泡过程中的某一轮如果没有进行任何位置交换,我们就认为排序已经完成,此时直接停止循环,程序结束。

优化后代码:

public class BubbleSortDemo {
    public static void main(String[] args) {
        int[] nums = {6, 2, 9, 5, 3, 7};
        System.out.println("排序前原始数组: " + Arrays.toString(nums));
        bubbleSort(nums);
        System.out.println("排序后的数组: " + Arrays.toString(nums));
    }

    private static void bubbleSort(int[] arr) {

        for (int i = 0; i < arr.length - 1; i++) {//外层循环,对应轮数
            boolean b = false;//每一轮冒泡开始前定义boolean变量
            for (int j = 0; j < arr.length - 1 - i; j++) {//内层循环,对应每轮的次数

                //比较交换
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    b = true;//进行了位置交换,所以让b为true
                }
            }
            if (!b) {//b仍为false表示该轮没有进行位置交换,即所有元素已经有序
                break;//退出循环
            }
        }
    }
}

        经过优化的代码会比前面的代码少进行若干轮冒泡循环,我们可以设置count属性记录冒泡轮数来做比较,这里不再赘述。

四、ending

        冒泡排序是所有排序算法的典中典,初学者大都会经历由懵到懂再到“切,什么玩意”的过程,另外冒泡排序也有其他写法,比如双层循环的逻辑等等。

2023年3月29日00:39:56 dgz

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值