细说冒泡排序及其五种优化算法

​01 冒泡排序

      冒泡排序算法思想简单来说:在内层一次遍历中,arr[j] 与 arr[j-1] 进行比较,如arr[j-1] < arr[j], 不改变,反之互换值,保证arr[j]存储着 0~j-1中的最大值,随一次遍历当前数组最大值也下沉至末尾,经过n-1次外层循环,可使n-1个元素下沉,最后一个元素位置确定,排序完成。

       举个例子方便理解,

        例1:例如原数组为:0,34,66,12,100,98

进入第一次冒泡排序:

       从下标1的元素(即34)排起:34与0比较,34大,数组仍为0,34,66,12,100,98

       下标2的元素(即66):66与34比较,66大,数组仍为0,34,66,12,100,98

       下标3的元素(即12):12与66比较,12小,互换位置,数组变换为0, 34, 12, 66, 100, 98

       下标4的元素(即100):100与66比较,100大,数组仍为0, 34, 12, 66, 100, 98

       下标5的元素(即98):98与100比较,98小,则互换位置,数组变换为0, 34, 12, 66, 98,100

       查看规律,排序过程中,下标 j的值在交换后,是0 ~ j-1中最大的,利用的是不等号具有传递性;排序完成后,将100沉底,再进行新的循环时,只需排序0, 34, 12, 66, 98即可,最大值沉底。

具体实现代码如下:

 

02 冒泡排序优化

外层优化:即减少外层循环次数

       举例2:假设元素数组为1, 0, 2, 4,8,那么只需一次内层遍历即完成了,何须四次?可优化为在每次遍历中增加一个tag记录,如果发生交换,则将tag = false,循环结束检测是否tag发生变化,未发生变化一定是排序完成。

具体实现如下:

 

内外层循环优化:即减少内层和外层循坏次数

       如咱们的例1:在一次排序后数据变换为 0, 34, 12, 66, 98,100, 那么第二次内层遍历只需遍历0, 34, 12即可,无需遍历至0, 34, 12, 66, 98,只需设置一个next记录最后交换位置,下一次循环就以next为终止。

具体实现如下:

 

双向冒泡:一次下沉,一次上浮操作,来回交替

       举例3:1000,2,34,56,343,0,一次下沉和上浮操作排序完成。虽然没有优化循环次数,但大大减少交换次数。

具体实现如下:

 

双向冒泡和外层优化一起配合使用

 

双向冒泡和内外层优化配合使用

 

03 冒泡优化效率对比

       现生成30万条数据使用以上冒泡排序+五种优化算法测试,测试结果如下:

 

相信大家对结果有些疑惑,我猜测解答一下:

问:内外层皆优化算法为什么慢于原冒泡排序算法?

答:和初始数据有关,内外层皆优化中如果多次使用next记录,但最后一个数值仍需交换,白白浪费之前赋值时间,再加之逻辑判断,所以慢于原冒泡算法,但大部分情况下优于原算法。

问:优化外层为什么能比内外层皆优化速度还快?

答:因为在两者逻辑判断中boolean型比==快的多,用1亿条循环测试如下:

 

 

 

问:优化算法的结果会发生改变吗?

答:会,因数据和数据量的不同会发生一定变化,特定条件下还可能产生相反的结果。即使采用统一数据,也可能因为对不同算法产生相反的影响。

 

 

 

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最小生成树(Minimum Spanning Tree, MST)是一种用于在加权无向连通图中找到最小生成树的算法。最小生成树是指在一个连通无向图中,选取一些边连接所有顶点,且这些边的边权之和最小。 下面给出两种最小生成树算法:Kruskal算法和Prim算法。 1. Kruskal算法 Kruskal算法是一种基于贪心策略的算法,其基本思想是先将图中所有边按照权值从小到大排序,然后依次选取每条边,并检查该边是否会形成环,如果不形成环,则将该边加入最小生成树中。 算法步骤: 1. 对图中所有边按照权值从小到大进行排序。 2. 依次选取每条边,如果该边不会形成环,则将该边加入最小生成树中。 3. 直到最小生成树中包含n-1条边为止。 下面给出一个使用Kruskal算法求解最小生成树的实例: ![kruskal_example](https://cdn.luogu.com.cn/upload/image_hosting/0x6m0q9j.png) 对于以上的图,我们按照边权从小到大进行排序,得到以下的边集合: {(1,2),(1,4),(2,3),(2,4),(3,4),(4,5),(5,6)} 依次选取每条边,并检查该边是否会形成环,最终得到的最小生成树为: ![kruskal_example_mst](https://cdn.luogu.com.cn/upload/image_hosting/3z4jyt0n.png) 2. Prim算法 Prim算法也是一种基于贪心策略的算法,其基本思想是从任意一个顶点开始,依次选择与当前已选顶点集合相邻且权值最小的边,并将其加入最小生成树中。 算法步骤: 1. 从任意一个顶点开始,将该顶点加入已选顶点集合。 2. 依次选择与当前已选顶点集合相邻且权值最小的边,并将其加入最小生成树中。 3. 直到最小生成树中包含n-1条边为止。 下面给出一个使用Prim算法求解最小生成树的实例: ![prim_example](https://cdn.luogu.com.cn/upload/image_hosting/n3x1it0v.png) 假设我们从顶点1开始,按照权值从小到大依次选择与当前已选顶点集合相邻且权值最小的边,并将其加入最小生成树中。得到的最小生成树为: ![prim_example_mst](https://cdn.luogu.com.cn/upload/image_hosting/3cx0d6x3.png)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值