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)。