Java温故而知新-冒泡法排序

时间:2024-07-31 20:35:02

冒泡法排序是各种初学者在学习数组与循环结构时都会练习的一种简单排序算法。

冒泡法的精髓在于比较相邻的两个元素,较大的元素会不断的排到队伍后面去,就像水里的泡泡一样不断向上跑。

想像一下倒在一个透明玻璃杯中的雪碧,杯底有很多个气泡,很多气泡同时向上升,现在我们抽象一下,假设气泡只能一个一个的向上升,那么所有气泡上升的过程就是排序的过程,实际上这样讲并不严谨。下面是一个例子。

先定义一个数组。预期排序后从小到大排列。

int[] arr = {9,6,8,2,7,1,5}; 里面的有7个元素 第一趟的排序后结果是 6 8 2 7 1 5 9

第二趟的排序后结果是 6 2 7 1 5 8 9

最后排序后的结果就是1 2 5 6 7 8 9


上面讲的很简略,也是大部分网上的教程所写的形式,有些天资超群的人一看就懂,但我们这些天赋更加超群的人还是需要看看更详细的分析。

第一趟排序中,是分几个小步完成的:

1、9和6作比较,9大,交换位置,序列变成 6982715

2、9和8做比较,9大,交换位置,序列变成 6892715

3、9和2作比较,9大,交换位置,序列变成 6829715

4、9和7作比较,9大,交换位置,序列变成 6827915

5、9和1作比较,9大,交换位置,序列变成 6827195

6、9和1作比较,9大,交换位置,序列变成 6827159

这样一趟下来就第一趟的排序后结果是 6 8 2 7 1 5 9,注意哦,这一趟我们排了6次。

第二趟也是这样排下来的:

1、6和8作比较,8大,不换位置,序列还是 6827159

2、8和2作比较,8大,交换位置,序列变成 6287159

3、8和7作比较,8大,交换位置,序列变成 6278159

4、8和1作比较,8大,交换位置,序列变成 6271859

5、8和5作比较,8大,交换位置,序列变成 6271589

这里8和9需不需要再比较呢,刚学的时候会有疑问,仔细想一想第一趟中,8和9已经比较过了,如果9和8的关系不确定,那么9就不会跑到最后面去了。所以这里不用再去比较最后的9和8了。实际上可以引入有序区和无序区的概念,每趟排序都会排出一个无序区中一个最大的数出来放到有序区去,那么有序区中的元素在放入的时候需不需要再排序呢,其实是不用的,你在构成有序区的时候已经默认了有序区第一个元素是最大的,第二个到有序区的元素是整个数组中第二大的,以此类推。注意哦,这一趟我们排了5次。

后面的几趟排序下来都可以用类似的方法去排下来。


那么如何在编码中实现呢?

整个排序分为两层,外层要控制排序的趟数,而且和序列的长度相关,仔细观察一下不难发现是序列长度-1。

伪代码

for(){

}

内层要做的是1控制该趟的比较次数,这个次数和第几趟有关;2比较相邻的两个元素,如果符合条件,就交换两个元素的位置,然后下一次比较就是往后面一位的相邻两元素。

伪代码

for(){
    for(){
        if(){//如果符合条件
            //交换元素
        }
    }
}

下面放源码

package com.chapter.five;

//需求 给入一个数组,输出一个从小到大排序好的数组,要求使用冒泡法
//思路
//冒泡法的精髓在于比较相邻的两个元素,较大的元素会不断的排到队伍后面去,就像水里的泡泡一样不断向上跑。
//1n个元素就要遍历n-1次,外层用一个for循环做
//2内层需要进行比较相邻的元素,如果符合第i个元素大于第i+1个元素,
//3就交换两元素的位置,然后比较下一对元素,也就是i+1和i+2之间(这里的i+1已经是换位过的较大数)的关系,
//这样就可以将较大的数不断的向后排出来
class BubbleSort{
    public static void main(String[] args){
        int[] arr = {9,6,8,2,7,1,5};
        BubbleSort bs = new BubbleSort();
        bs.bubbleSort(arr); 

    }
    void bubbleSort(int[] arr){
    System.out.println("排序前的数组是");
        for(int i:arr){
        System.out.print(i+" ");
    }
    for(int i = 0;i < arr.length;i++){//定量,冒泡一共进行多少次,实际上应该是长度减1次
        for(int j = 1;j < arr.length-i;j++){//因为进行了i次排序时,后面的第i位已经是有序的了,所以是长度减1
            if(arr[j-1] > arr[j] ){//如果符合条件就交换位置,不符合就不交换
                int temp = arr[j-1];
                arr[j-1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    System.out.println("排序后的数组是");
        for(int i:arr){
        System.out.print(i+" ");
    }
    }  

}