JAVA排序之冒泡排序

冒泡排序是以从小到大排序为例,每一轮排序就找出未排序序列中最大值放在最后。像金鱼吐泡泡,越到后面越大,所以叫冒泡排序。

基本的冒泡排序算法:

public class BobbleSort {

    public static void bubblySort_1(int []num){
        for (int i=0;i<num.length;i++){//表示遍历次数减1
            for (int j=1;j<num.length-i;j++){//依次与后面的相比较
                if (num[j-1]>num[j]){//如果前面的比后面的大,交换变量
                    int temp;//设置中间交换变量
                    temp=num[j-1];
                    num[j-1]=num[j];
                    num[j]=temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int num []={12,78,2,9,7,5};
        bubblySort_1(num);

        for(int i:num){
            System.out.print(i+" ");
        }
    }
}

结果:

2 5 7 9 12 78 

但是这个的时间复杂度为O(n∧2),如果对于一个本身有序的序列,或则序列后面一大部分都是有序的序列,上面的算法就会浪费很多的时间开销,所以可以将这个算法进行优化,设置一个flag标志,如果这一趟发生了交换,则为true,否则为false,如果有一趟没有发生交换,说明已经是有序队列。

优化的冒泡排序算法:

    public static void bubbleSort_2(int [] num){
        int n=num.length;
        boolean flag = true;//发生了交换就为true
        while (flag){
            flag=false;//每次开始排序前,重置
            for(int j=1; j<n; j++){
                if(num[j-1] > num[j]){
                    int temp;
                    temp = num[j-1];
                    num[j-1] = num[j];
                    num[j]=temp;

                    //表示交换过数据;
                    flag = true;
                }
            }
            n--;//减少一次排序
        }
    }

    public static void main(String[] args) {
        int num []={12,78,2,9,7,5};
        //bubblySort_1(num);
        bubbleSort_2(num);

        for(int i:num){
            System.out.print(i+" ");
        }
    }

结果:

2 5 7 9 12 78 

如果有100个数的数组,仅前面10个无序,后面90个都已排好序且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小于10,且这个位置之后的数据必定已经有序了,记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。

再次优化的冒泡排序算法:

 public static void bubbleSort_3(int [] num){
        int k;
        int flag = num.length ;//flag来记录最后交换的位置,也就是排序的尾边界

        while (flag > 0){//排序未结束标志
            k = flag; //k 来记录遍历的尾边界
            flag = 0;

            for(int j=1; j<k; j++){
                if(num[j-1] > num[j]){
                    int temp;
                    temp = num[j-1];
                    num[j-1] = num[j];
                    num[j]=temp;

                    flag = j;//记录最新的尾边界.
                }
            }
        }
    }

    public static void main(String[] args) {
        int num []={12,2,2,9,7,9,10,14,25,36,54};
        //bubblySort_1(num);
        //bubbleSort_2(num);
        bubbleSort_3(num);
        for(int i:num){
            System.out.print(i+" ");
        }
    }

结果:

2 2 7 9 9 10 12 14 25 36 54 

双向冒泡排序,此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序

双向冒泡排序算法:


public class BobbleSort {
    public static void bubbleSort_4(int[] num) {
        int len = num.length;
        int left = 0, right = len -1;

        while (left<right){
            //最坏的情况下也至少为1个数
            int flagLeft = left + 1;
            int flagRight = right - 1;

            //从左往右找出最大的数
            for (int j = left;j<right;j++){
                if (num[j]>num[j+1]){
                    int temp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = temp;

                    //记录下最后交换的位置,flagRight后面的数表示已经完成排序(也有可能是最后的一个数)
                    // 右排序完成一次,后面的左排序只需要排这个flagRight之前的
                    //flagRight之后的数已经完成好了排序
                    flagRight = j;
                }
            }
            right = flagRight;


            for (int j = right;j>left;j--) {
                if (num[j] < num[j - 1]) {
                    int temp = num[j-1];
                    num[j - 1] = num[j];
                    num[j] = temp;

                    //记录下最后交换的位置,flagLight前面的数表示已经完成排序(也有可能是第一个数)
                    // 左排序完成一次,下一次的排序只需要从flagLight之后开始排序
                    //flagLight之后的数已经完成好了排序
                    flagLeft = j;
                }
            }

            left = flagLeft;
        }

    }

    public static void main(String[] args) {
        int [] num = new int[10];
        //随机数
        for (int i = 0;i< 10;i++){
            num[i] = (int)(Math.random()*100);
        }

        bubbleSort_4(num);
        for(int i:num){
            System.out.print(i+" ");
        }
    }
}

结果:

7 20 26 26 37 57 63 73 77 98 

差不多我所理解的就是这些了,欢迎留言讨论,转载请注明出处,谢谢!


猜你喜欢

转载自blog.csdn.net/pengbo1996/article/details/79888505