【DS】排序算法之冒泡排序(Bubble Sort)

1、算法思想前端

    冒泡排序是排序算法中比较有意思的一种排序方法,也很简单。其算法思想以下:算法

1)比较相邻的元素。若是第一个比第二个大,就交换他们两个。数组

2)对每一对相邻元素做一样的工做,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。优化

3)针对全部的元素重复以上的步骤,除了最后一个。spa

4)持续每次对愈来愈少的元素重复上面的步骤,直到没有任何一对数字须要比较。code

 

2、算法示意图blog

     这幅图形象的展现了冒泡的过程,最左边一列,从下往上显示了等待排序的数列,最后一列则显示了冒泡排序的最终结果。每一列阴影的部分表明等待排序的数列,黄色部分表示排序完成的部分,冒泡过程当中不须要涉及黄色部分,咱们解释一下第二列的造成过程:排序

     第二列在冒泡过程当中(从下往上看),首先比较2和3,2<3,则交换;比较3和4,4>3,不须要交换;比较4和9,9>4,不须要交换,比较1和9,1<9,交换;比较5和9,5<9,交换;比较7和9,7<9,交换;比较6和9,6<9,交换;比较8和9,8<9,交换。这样就造成了第二列。第二列造成之后,9,也就是最后的数字已是最大的了,第二趟这样进行造成第三列的时候,就不须要进行到9了。class

     每一趟冒泡,都是将灰色数列部分中最大的数字选择出来放到黄色部分的最下层,由此造成下一列,最大数字的选择是经过数字的交换来完成的——算法会从数列的最前端开始日后遍历,若是发现某一个数比它前面的数字小,就会进行交换,把较大的数字日后移动。由此不断进行,就能够将最大的数字移动到数列灰色部分的最后。遍历

 

3、Java代码

 1 //@wiki
 2 public class BubbleSort extends Sort {
 3     public static void sort(int[] array) {
 4         int temp = 0;
 5         for (int i = array.length - 1; i > 0; --i) {
 6             for (int j = 0; j < i; ++j) {
 7                 if (array[j + 1] < array[j]) {
 8                     temp = array[j];
 9                     array[j] = array[j + 1];
10                     array[j + 1] = temp;
11                 }
12             }
13         }
14     }
15 }

 

4、算法复杂度

      从上面的Java代码来看,第7行的比较是必定会进行的,假设数组元素是n,则进行的次数是:n*(n-1)/2。由于j是从0~i-1,而i是从n-1~1,因此简单计算就能够得出以上的结果。

      最差的状况固然是每次都执行if条件判断,而且执行其中的8,9,10三行语句,总体复杂度为4*n^2。出现最坏的状况就是一开始数列是倒叙排列的,即按照从大到小的顺序排列的,致使每一次比较都须要交换。

      在本代码中,最好的状况其实不能达到,咱们去看示意图,咱们发现五列已经完成了排序,第6,7,8列的排序过程其实能够省略。因此,冒泡排序能够优化,咱们增长一个flag,当一趟冒泡完成时咱们发现没有发生交换行为,就能够终止冒泡了,其代码以下:

 1 public class BubbleSort extends Sort {
 2     public static void sort(int[] array) {
 3         int temp = 0;
 4         for (int i = array.length - 1; i > 0; --i) {
 5             boolean exchange = false;
 6             for (int j = 0; j < i; ++j) {
 7                 if (array[j + 1] < array[j]) {
 8                     exchange = true;
 9                     temp = array[j];
10                     array[j] = array[j + 1];
11                     array[j + 1] = temp;
12                 }
13             }
14             if(!exchange)
15                 return;
16         }
17     }
18 }

      如上,这样,咱们能够将最好的复杂度下降为n,状况出如今数列一开始就是从小到大排列的时候,只须要遍历一边,exchange始终为false,直接返回,这样就能够获得最好的时间复杂度,为O(n),所以平均时间复杂度为O(n^2)

      空间复杂度很是容易,由代码能够看出来,只须要一个位置temp用于交换便可,所以是O(1)

相关文章
相关标签/搜索