白话数据结构-冒泡排序与优化

冒泡排序

主要思路:
从头到尾遍历数组,比较当前元素与下一个元素,如果当前元素更大就交换他俩的位置。一次遍历结束后,最大的对象将被移至尾端。然后从头开始第二次遍历,但因为上一轮最大对象已被移至队尾,此遍历可在n-1处停止。

例:
第一趟遍历:
(5 1 4 2 8) - >(1 5 4 2 8),这里,算法比较前两个元素,因为5> 1,交换他俩。
(1 5 4 2 8) - >(1 4 5 2 8),因为5> 4,交换他俩。
(1 4 5 2 8) - >(1 4 2 5 8),因为5> 2,交换他俩。
(1 4 2 5 8) - >(1 4 2 5 8),现在,因为5<8,不交换。

第二趟遍历:
(1 4 2 5 8) - >(1 4 2 5 8)
(1 4 2 5 8) - >(1 2 4 5 8),从4> 2开始交换
(1 2 4 5 8) - >(1 2 4 5 8)
(1 2 4 5 8) - >(1 2 4 5 8)
现在,数组已经完成排序,但电脑是不知道它是否已完成排序的, 如果是未经优化的最简易冒泡算法,我们只用按元素个数设置循环次数就可以,但这种简易冒泡对于已经排好序的数组仍然会强制遍历n次,增加了耗时,所以改良的冒泡算法会记录一次遍历中元素交换的次数,如果某一次遍历中交换次数为0那么排序就已经完成了。如当前例子,简易冒泡需要5趟遍历,但改进冒泡只需要三趟遍历;

第三趟遍历:
(1 2 4 5 8) - >(1 2 4 5 8)
(1 2 4 5 8) - >(1 2 4 5 8)
(1 2 4 5 8) - >(1 2 4 5 8)
(1 2 4 5 8) - >(1 2 4 5 8)

public class bubbleSort{
    public static void main(String[] args){
       int[] inputs = {5,4,3,2,1};

       for (int i = 0; i< inputs.length;i++) {
           int flag = 0;
           for (int j = 0; j < inputs.length - 1 -i; j++) {
               if (inputs[i] > inputs[i + 1]) {
                   //比大小,交换对象
                   int temp = inputs[i + 1];
                   inputs[i + 1] = inputs[i];
                   inputs[i] = temp;
                    //统计交换次数
                   flag++;
               }
           }
            if (flag==0){
                //如果此循环没有进行交换则排序完成,停止遍历
                break;
            }
       }
        System.out.println("Sorting finished! ");
        for(int number: inputs){
            System.out.println(number);
        }
    }
}

冒泡算法的时间复杂度

  1. 最佳情况 best case
    给出的数组已经是排序好了的{1,2,3,4,5},但此时算法仍需要至少遍历一次数组。所以时间复杂度为Ω(n)。
    这里使用的是大omega符号,因为Ω()就是用来描述算法在最佳情况时用时下限的
  2. 最糟情况 worst case
    给出的数组刚好是从大到小倒序的{5,4,3,2,1},此时,第一遍遍历,n-1次比较,第二遍n-2次,第三遍n-3次....最后一遍1个对象,再有一个无交换的遍历(具体的对比和交换次数取决于你怎么优化你的算法!)。总数为1+2+3+...n= (n*(n + 1))/2 = O(n²/2)= O(n²)
    这里使用的是大O符号,因为O()就是用来描述算法在最差情况时用时的上限的
  3. 平均情况 average case
    平均情况的比较次数是和最糟情况一样的,但是交换次数少一些,平均的话就是最糟的一半, O(n²/4)= O(n²),标准的写作Ө(n²)。

你可能感兴趣的:(白话数据结构-冒泡排序与优化)