【图解算法】冒泡排序的分析推导与实现(附加速度测试)

冒泡排序

在这里插入图片描述
通过对排序序列从前向后(从下标最小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移到后部,就像水底下的气泡一样逐渐向上冒

如果一趟下来没有进行过交换就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换,从而减少不比较的比较

思路

有这样一个数组arr {5,6,4,3,2,1},使用冒泡排序从小到大

第一趟排序:

5 6 4 3 2 1
5 4 6 3 2 1
5 4 3 6 2 1
5 4 3 2 6 1
5 4 3 2 1 6

最大的6已经交换到了最右边

第二趟排序:

4 5 3 2 1 6
4 3 5 2 1 6
4 3 2 5 1 6
4 3 2 1 5 6
4 3 2 1 5 6

最大的5交换到6的后面

第三趟排序:

3 4 2 1 5 6
3 2 4 1 5 6
3 2 1 4 5 6
3 2 1 4 5 6

最大的4交换到5的后面

第四趟排序

2 3 1 4 5 6
2 1 3 4 5 6
2 1 3 4 5 6

最大的3交换到4的后面

第五趟排序

1 2 3 4 5 6
1 2 3 4 5 6

最大的2交换到3的后面,然后最后一次比较没有发生交换,冒泡结束

总结:

  • 冒泡排序一共进行数组元素个数-1趟交换
  • 每趟排序的次数在逐渐减少

推导

声明数组arr
在这里插入图片描述
根据上面的思路,第一趟交换进行了arr.length-1次,如果数组的第一个元素大于第二个元素,那么就发生交换,代码如下:
在这里插入图片描述
第二趟就只比较arr.length-2次,因为最大的数已经被交换到最右边了
在这里插入图片描述
第三趟、第四趟、第五趟都同理可得,比较的数越来越少,因为比较的趟数
等于数组元素个数-1,所以当数组元素个数为n时,趟数为n-1,也就是
在这里插入图片描述
假设趟数为i,只要在上面代码外面套一层for循环,然后让i去递增即可,所以

最后代码实现如下:

实现

在这里插入图片描述

优化

优化主要是根据思路而来,思路中,每趟排序有多次,而当有一次比较没有发生交换,就意味着不需要再进行比较了
在这里插入图片描述

速度测试

增加一个80000个 数的数组
在这里插入图片描述
获取当前时间
在这里插入图片描述
获取排序后时间
在这里插入图片描述
优化之后的执行结果,13秒
在这里插入图片描述

注释优化的代码
在这里插入图片描述
优化之前是15秒
在这里插入图片描述
需要多次执行再比较,优化之后的时间大多数是要小于优化之前的时间的,这是因为CPU有其他情况,不一定每次执行时间一致

小结

  • 时间复杂度
    优化之前的时间复杂是O(N²),优化之后 O(N)
  • 空间复杂度,就是借用了flag这个变量需要申请空间
    最优的空间复杂度,同样,就是不需要借用第三方内存空间,则复杂度为0
    最差的空间复杂度就是开始元素逆序排序,每次都要借用一次内存,按照实际的循环次数,为O(N)

冒泡排序是稳定的,因为每次都是相邻的两个两两交换

猜你喜欢

转载自blog.csdn.net/yujing1314/article/details/106389558