冒泡排序交换次数证明

我来尝试解答一下这个问题,主要是要给出严格证明

原理比较微妙,实际上也很简单

Donald E. Knuth著计算机程序设计艺术卷3:排序与查找(第二版)中译本 贾洪峰 译 人民邮电出版社

p8提到了 1 , 2 , − − − , n 1,2,---,n 1,2,,n的排列 a 1 a 2 − − − a n a_{1}a_{2}---a_{n} a1a2an 反序表 b 1 b 2 − − − b n b_{1}b_{2}---b_{n} b1b2bn 的概念,请先熟悉一下这个概念

设第k轮冒泡开始前被排序序列为 a 1 a 2 − − − a n − k + 1 a n − k + 2 − − − a n a_{1}a_{2}---a_{n-k+1}a_{n-k+2}---a_{n} a1a2ank+1ank+2an , n n n为被排序元素个数

a n − k + 2 − − − a n a_{n-k+2}---a_{n} ank+2an 为已经沉底的前 k − 1 k-1 k1大元素, a 1 a 2 − − − a n − k + 1 a_{1}a_{2}---a_{n-k+1} a1a2ank+1 为排序区

然后根据本书p83页定理I.的证明我们可以看出,对于冒泡排序中第k轮当前扫描到的位置i(i不是被排序序列的第一个位置且i位于本轮冒泡中被排序的区域,而不位于已经沉到排序序列底部的最大的若干元素,即 1 < i < n − k + 2 1<i<n-k+2 1<i<nk+2 ),设位置i上的被排序元素为 a i a_{i} ai ,如果i前面有比 a i a_{i} ai 更大的元素,则 a i a_{i} ai 必和i前面所有元素中的最大元素交换,而根据冒泡排序的执行过程,本轮冒泡中i 处元素和它前面相邻元素的交换只会执行这一次,而该次交换发生后 b a i b_{a_{i}} bai 恰减1(注意随后其值一直保持不变直到本轮冒泡结束),另外如果i前面没有比 a i a_{i} ai 更大的元素,则本轮冒泡中i处元素 a i a_{i} ai 不会和它前面相邻元素发生交换,不会执行位置i和其前面相邻位置的交换并且 b a i b_{a_{i}} bai 保持不变为0.此外由已经沉底的最大诸元素构成的非排序区中的任意位置 j ( n − k + 1 < j < = n ) j(n-k+1<j <=n) j(nk+1<j<=n) 满足在本轮冒泡中 a j a_{j} aj 没有和前面相邻元素交换且 b a j b_{a_{j}} baj 保持不变为0 最后注意到位置1前面没有元素且 b a 1 b_{a_{1}} ba1 在本轮冒泡中保持不变为0(因为 a 1 a_{1} a1 就算被交换到后面其前面元素也不可能比它大)

由此可知,在第k轮冒泡中,任意位置i上的元素和其前面相邻位置上的元素发生交换当且仅当 b a i b_{a_{i}} bai 减1,因此第k轮冒泡中交换操作的总次数恰为本轮冒泡中满足 b a i b_{a_{i}} bai 被减1的i的数目,因此任意一轮冒泡中的交换次数即为反序表 b i 1 < = i < = n b_{i}1<=i<=n bi1<=i<=n 中被减1的元素个数,我们知道当反序表中的元素全为0时(再经过一轮冒泡,但最后一轮冒泡没有发生交换)冒泡排序终止,且当且仅当 b i b_{i} bi 不为0时才会被减1,因此结合以上几个结论,冒泡排序的交换总次数就是初始序列的反序表 b 1 b 2 − − − b n b_{1}b_{2}---b_{n} b1b2bn 所有元素变成0所需的减1操作的总数目, b i b_{i} bi 变为0所需的减1操作的总数目即为 b i b_{i} bi ,从而反序表所有元素变成0所需的减1操作的总数目是 ∑ i = 1 n \sum_{i=1}^{n} i=1n b i = b 1 + − − − + b n {b_{i}}=b_{1}+---+b_{n} bi=b1++bn ,此即冒泡排序的总交换次数,也就是初始排列的逆序数

证毕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值