冒泡排序—分步实现

首先,我们来了解一下冒泡排序的定义:对于一组要排序的元素列,依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面,如此继续,直到比较到最后的两个数,将小数放在前面,大数放在后面,重复步骤,直至全部排序完成。

(完整代码在最下面)

通俗一点来说就是元素挨个交换,小的放前面,大的放后面,图引自官方

冒泡排序—分步实现_第1张图片

具体思想如下:

首先,我们很容易想到这用循环来做,从图解可以看出,一共排了(数组长度-1轮),没看出来的小伙伴可以多看几遍动图

所以,第一轮排序的代码是

    public static void BubbleSort(int[] arr) {
        //temp的作用是临时存放数组值,以便两数交换
        int temp = 0;
            for (int j = 0; j < arr.length - 1; j++) {
                //如果前面的数大于后面的数,就进入if交换,否则下次循环
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
    }
}
   

这样第一轮就排好了,而且整个数组中最大的数一定会排到最后,接下来第二轮

    public static void BubbleSort(int[] arr) {
        int temp = 0;
            for (int j = 0; j < arr.length - 1 - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
      }  

有的小伙伴就有疑惑了,为什么for循环里的限制循环条件比上一轮循环还要减1呢?

因为第二轮循环之前,数组中最大的那个数已经排好序了,所以就这轮循环较上次少了一次比较。

下面第三轮...

    public static void BubbleSort(int[] arr) {
        int temp = 0;
            for (int j = 0; j < arr.length - 1 - 2; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
    }
    

第三轮思路也和前两轮一样,排好序的就不用再排了,所以到这里就发现规律了,每增加一轮排序,就会较上次少比较一次,以此类推,for循环外面可以再增加一个for循环,来控制每轮的排序次数,保证次次递减

    public static void BubbleSort(int[] arr) {
        int temp = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

        我们用 i 来控制每一轮循环的次数,每轮减i,这样到了最后一轮只排序一次就足够了,但是,不是每一轮排序都需要交换的,如果还没等到循环完就已经排好序了,再运行代码会导致没必要的内存消耗,所以我们需要优化一下冒泡排序。


 

我们可以用一个flag来标记一下。

public class bubblesort {
    public static void main(String[] args) {
        int arr[] = {9,5,-1,23,66,11};
        BubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void BubbleSort(int[] arr) {
        int temp = 0;
        boolean flag = false;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!flag){
                break;
            }else{
                flag = false;
            }
        }
    }
}

flag的思想是:初始置空,如果进入if,flag为true,说明本轮循环交换过,退出第一轮循环判断flag(如果flag为break,说明这一轮循环已经排好序了,没进到if里改变flag的值,依然为flase,直接break退出循环;否则就让flag初始化继续下轮循环)

欢迎在下方留言,侵删!

你可能感兴趣的:(排序算法,数据结构与算法——java,排序算法)