当前位置: 首页 > 后端技术 > Java

算法总结——冒泡排序

时间:2023-04-01 19:42:26 Java

算法定义冒泡排序是交换排序的一种,是一种比较简单的排序算法。按照维基百科的定义,就是反复访问待排序元素所在的列,依次比较相邻的两个元素,顺序不对就进行交换。重复访问元素的工作,直到不需要交换相邻元素为止,也就是说元素列已经排序完毕。这个算法的名字来源于较小的元素会通过交换慢慢浮到序列的顶端,就像碳酸饮料中的二氧化碳气泡最终会浮到顶端,所以命名为“冒泡排序”.算法原理冒泡排序算法的原理如下:1.比较一对相邻的元素,如果第一个元素大于第二个元素,则交换这对元素。2、对所有相邻的元素重复步骤1,从第一对元素到最后一对还没有确定的元素。这一步完成后,确定剩余元素中最大的元素。3.对越来越少的剩余元素重复步骤1和2,直到确定当前所有剩余元素中最大的元素。代码实现遵循以上思路,初步代码如下:publicclassMain{//冒泡排序(交换排序),时间复杂度O(n^2),空间复杂度O(1)publicstaticvoidbubbleSort(int[]arr){//排序的次数恰好是数组长度arr减1,每次排序的时候,找出当前最大的数,移动到对应的位置for(inti=0;iarr[j+1]){//如果当前元素大于下一个元素,交换两个元素arr[j]^=arr[j+1];arr[j+1]^=arr[j];arr[j]^=arr[j+1];}}}}}但是上面代码的时间复杂度固定为O(n^2),如果数组已经有序了,再进行元素交换是多余的,或者元素交换个数时数组变得有序times到了一半,后面进行元素交换也是多余的,所以上面的代码是有缺陷的,需要改进。假设数组的长度为n。最好的情况:数组是有序的,所以不需要交换元素。当第一层for循环i=0时,进行第二层for循环。第二层for循环结束后,判断数组有序,结束。这个过程只走了一趟,但没有进行元素交换,每趟花费的时间在n量级,所以最好情况下的时间复杂度是O(n)。最坏情况:数组倒序,则需要进行n-1次元素交换,每次元素交换所花费的时间在n量级,所以最坏情况时间复杂度为O(n^2)。平均情况:平均情况下的行程次数可以表示为n-1-k,k为常数,每次元素交换所花费的时间也在n量级,那么平均情况下所花费的时间是(n-1-k)n,平均时间复杂度=总花费时间/所有情况的数量。因为不同的情况表现出不同的行程次数,所有情况的次数等于n阶,总花费的时间=平均情况花费的时间所有情况的次数,即(n-1-k)nn,平均时间复杂度=总花费时间/所有情况的个数=(n-1-k)nn/n=(n-1-k)n,因为k是常量,所以(n-1-k)n实际上是n^2数量级,所以平均时间复杂度为O(n^2)。根据以上分析,改进后的代码如下:publicclassMain{//冒泡排序改进(交换排序),平均时间复杂度O(n^2),最佳时间复杂度O(n),最坏时间复杂度O(n^2),空间复杂度O(1)publicstaticvoidbubbleSort2(int[]arr){//排序的次数正好是数组长度arr减1,每次排序都找当前的最大值number,移动到对应位置for(inti=0;iarr[j+1]){//如果当前元素大于下一个元素,交换两个元素arr[j]^=arr[j+1];arr[j+1]^=arr[j];arr[j]^=arr[j+1];//如果有交换,则数组没有顺序flag=false;}}if(flag){//如果数组已经有序,结束循环break;}}}}算法效率高冒泡排序是一种稳定的排序算法。最好的情况是数组是有序的,不需要交换元素。只需走一趟,时间复杂度为O(n);最坏的情况是数组颠倒了,每次都要交换元素。n-1次交换元素,时间复杂度为O(n^2);平均下来,根据上面的计算,时间复杂度为O(n^2);交换元素时,如果采用引入中间变量的方式,中间变量会占用一个空间。上述代码采用位运算的方式交换元素,没有引入中间变量。无论采用哪种方法,空间复杂度都是O(1)平均时间复杂度:O(n^2)最佳时间复杂度:O(n)最差时间复杂度:O(n^2)空间复杂度:O(1)参考冒泡排序动力学图片来自:冒泡排序原文链接