java冒泡排序

经典算法——冒泡排序(Bubble Sort)

一、示例代码(伸手党看这里)

1.示例一

import java.util.Arrays;

public class BubbleSort {
    public static void bubbleSort(int[] arr){
        int temp;  /* 临时变量,交换数据时使用  */
        int length = arr.length;
        for(int p = length-1; p > 0; p--){  /* 需要进行N-1(数组长度减一)趟排序  */
            for(int i = 0; i < p; i++){  /* 开始排序 */
                if(arr[i] > arr[i+1]){
                    // 进行位置交换
                    temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }
    }
    
    public static void main(String[] args) {
        int[] a = {10, 2, 5, 7, 23, 59, 3};
        bubbleSort(a);
        System.out.println(Arrays.toString(a));        
    }
}

当然,上面的代码可以小小的优化一下。

在使用冒泡排序的时候有可能会遇到这样一种情况:某一趟排序从头到尾,数组中的数字都没有发生位置交换。

那么上面这种情况说明了什么呢?说明了在经过上一趟的排序后,整个数组就已经被排好序了。

这么说的话原来计划的N-1趟排序我们是不是可以不用跑满了?是的!

所以可以优化的地方是:在每一趟排序排完后,看一下这一趟有没有发生数字位置的交换(形象点说就是看看这趟有没有白跑233)。我们借助一个变量实现这个功能。

2.示例二(优化后的冒泡排序)

与示例一不同的地方用红色字体标出

import java.util.Arrays;

public class BubbleSort {
    public static void bubbleSort(int[] arr){
        int temp;  /* 临时变量,交换数据时使用  */
        int length = arr.length;
        for(int p = length-1; p > 0; p--){  /* 需要进行N-1(数组长度减一)趟排序  */
            int flag = 0;  /* 一个标识变量,如果某一趟排序时数组中的数字发生了位置交换,其值变为1 */
            for(int i = 0; i < p; i++){  /* 开始排序 */
                if(arr[i] > arr[i+1]){
                    // 进行位置交换
                    temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                    flag = 1;
                }
            }            
            if(flag == 0){
                break;  /* 全程无交换 */
            }
        }
    }
    
    public static void main(String[] args) {
        int[] a = {10, 2, 5, 7, 23, 59, 3};
        bubbleSort(a);
        System.out.println(Arrays.toString(a));        
    }
}

二、冒泡排序原理

1.原理

依次比较数组中两个相邻的数,将值大的放在右边。这样看起来数组中的数字就像水底的泡泡,越往上浮,越接近水面(数组的最右边)变得越大。

2.实现思路

假设数组中有5个数。我们依次比较相邻的两个数,将小数放在前面,大数放在后面。

第一趟排序:

先比较第一个数和第二个数,把小的放左边,大的放右边;

再比较第二个数和第三个数,把小的放左边,大的放右边;

然后比较第三个数和第四个数,把小的放左边,大的放右边;

最后比较第四个数和第五个数,把小的放左边,大的放右边;

上述操作做完了之后,第一趟排序也就排完了。来看看有什么特征,你会发现这时候数组的最右边的一个数(也就是数组中最后一个数)是数组中最大的数。

好了,完成了第一趟排序我们选出了大哥(数组中最大的数字),并且大哥坐上了第一把交椅(数组最右边)。

既然大哥位子坐稳了,就不用参与接下来的斗争了,安心的看着剩下的小弟们选出二哥就行了。

开始第二趟排序:

先比较第一个数和第二个数,把小的放左边,大的放右边;

再比较第二个数和第三个数,把小的放左边,大的放右边;

最后比较第三个数和第四个数,把小的放左边,大的放右边;

第二趟排序完成后,我们选出了二哥,并且二哥坐上了第二把交椅(数组的倒数第二个位置)

开始第三趟排序:

先比较第一个数和第二个数,把小的放左边,大的放右边;

再比较第二个数和第三个数,把小的放左边,大的放右边;

第三趟排序完成后,我们选出了三哥,并且三哥坐上了第三把交椅(数组的倒数第三个位置)

开始第四趟排序:

比较第一个数和第二个数,把小的放左边,大的放右边;

第四趟排序排完后就变成了这样:老四坐第四把交椅(数组的第四个位置),弟中弟老五在瑟瑟发抖(数组的第一个位置)。

当数组完全逆序的时候以上四趟排序会全部发生。也就是常说的N个数要排N-1趟序。

三、时间复杂度

1.最好的情况

当数组是一个从小到大完全有序的数组时:需要将数组遍历一遍所以此时的时间复杂度是O(n)

2.最坏的情况

当数组完全逆序的时候:需要跑完N-1趟,每一趟需要比较N-1次,此时的时间复杂度是O(n²)

3.平均复杂度

结合上述1和2两种情况,冒泡排序的平均时间复杂度是O(n²)

纯手工原创,觉得写得不错点个赞支持下吧  :)

原文地址:https://www.cnblogs.com/lmw97/p/11018715.html