欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 双向冒泡排序学习

双向冒泡排序学习

2024/10/24 9:21:33 来源:https://blog.csdn.net/weixin_72137075/article/details/140830685  浏览:    关键词:双向冒泡排序学习

  本博客主要考虑冒泡排序的扫描次数的问题。特别地,以升序排序为例,考虑冒泡排序中单向、双向的情况。启发来自洛谷的这道题。

单向冒泡排序

  这是最简单的一种冒泡排序,其伪代码如下:

sorted = false
while (not sorted):sorted = truefor i = 0 to N-2:if A[i+1] < A[i]:swap A[i], A[i+1]sorted = false

  单向冒泡排序每一轮扫描都能确定数组A的最后一个元素,动态演示如下:

图源这篇博客。

  那么问题来了,如果采用上面的伪代码,已知一个序列A[1...N],如何提前得知冒泡排序需要扫描多少轮

直接模拟

  一个简单的想法是直接进行模拟。也就是设置一个计数器cnt,在while语句块的开头进行++cnt,就能够得知需要扫描多少次。然而它的时间复杂度是 O ( n 2 ) O(n^2) O(n2)

更快的方法

  我们仔细观察上面的动图,可以获得更一般性的结论:

  • 考虑序列中一个固定的数 x x x,如果它前面有比自己大的数,那么每轮扫描都将使 x x x 前面比 x x x 大的数的个数减少 1 1 1
  • 当每个数前面都没有比自己大的数时,排序完成。
  • 最好的情况给出的序列直接是升序的,至少需要扫描 1 1 1 次。

  所以,我们可以直接得到,扫描的次数 X = max ⁡ ( 1 , max ⁡ 1 ≤ i ≤ n ( ∑ j = 1 i − 1 [ a j > a i ] ) ) X=\max(1,\max_{1\leq i\leq n}(\sum_{j=1}^{i-1}[a_j>a_i])) X=max(1,max1in(j=1i1[aj>ai]))。其中 [ ] [] [] 表示取布尔表达式的值,为真值就是 1 1 1,为假值就是 0 0 0。更通俗一点就是: X = max ⁡ ( 1 , 每个数前面有几个比自己大的数 ) X=\max(1,每个数前面有几个比自己大的数) X=max(1,每个数前面有几个比自己大的数)
  这种方式可以在 O ( n ) O(n) O(n) 的复杂度内解决问题。

双向冒泡排序

  这种排序方式,每一轮扫描的方式是:先从前往后扫描一次,再从后往前扫描一次。伪代码如下:

sorted = false
while (not sorted):sorted = truefor i = 0 to N-2:if A[i+1] < A[i]:swap A[i], A[i+1]for i = N-2 downto 0:if A[i+1] < A[i]:swap A[i], A[i+1]for i = 0 to N-2:if A[i+1] < A[i]:sorted = false

  固然也可以用 O ( n 2 ) O(n^2) O(n2) 的方法模拟出扫描次数,但是依然有 O ( n ) O(n) O(n) 的简单办法。

离散化

  首先要把给到的序列 { a i } ( i = 1 , 2 , ⋯ , n ) \{a_i\}(i=1,2,\cdots,n) {ai}(i=1,2,,n) 离散化。离散化可以这样理解,每个数 a i → 1 + ∑ j = 1 n [ a j < a i ] a_i\rightarrow 1+\sum_{j=1}^n[a_j<a_i] ai1+j=1n[aj<ai],中括号的含义同上。说白了就是把 a i a_i ai 改成它是序列中第几小的数。如: { 1 , 1 , 4 , 5 , 1 , 4 } → { 1 , 1 , 2 , 3 , 1 , 2 } \{1,1,4,5,1,4\}\rightarrow\{1,1,2,3,1,2\} {1,1,4,5,1,4}{1,1,2,3,1,2}

扫描序列

  注意到关于双向冒泡排序的以下结论:

  • 考虑固定的 x x x,如果离散化之后的序列中,前 x x x 个数中没有比 x x x 大的,那么这些数就被锁在了 [ 1 , x ] [1,x] [1,x] 中,不会与 [ x + 1 , n ] [x+1,n] [x+1,n] 产生直接或者间接的交换。
  • 考虑固定的 x x x,如果离散化之后的序列中,前 x x x 个数中有比 x x x 大的,那么最大的那个在正向扫描时将被移出 [ 1 , x ] [1,x] [1,x],同时反向扫描时引入 [ 1 , x ] [1,x] [1,x] 的新数必定小于等于 x x x
      记 { a i } \{a_i\} {ai} 离散化得 { b i } \{b_i\} {bi},那么扫描的次数就是 X = max ⁡ ( 1 , max ⁡ 1 ≤ i ≤ n ( ∑ j = 1 i [ b j > i ] ) ) X=\max(1,\max_{1\leq i\leq n}(\sum_{j=1}^i[b_j>i])) X=max(1,max1in(j=1i[bj>i]))。更通俗一点就是: X = max ⁡ ( 1 , 第 1 到第 i 个数中有几个比 i 大的数 ) X=\max(1,第 1 到第i个数中有几个比i大的数) X=max(1,1到第i个数中有几个比i大的数)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com