(冒泡排序的正确性) 冒泡排序是一种流行但低效的排序算法,它的作用是反复交换相邻的未按次序的排列的元素.
BUBBLESORT(A)
1 for i = 1 to A.length - 1
2 for j = A.length downto i + 1
3 if A[j] < A[j - 1]
4 exchange A[j] with A[j-1]
a. 假设A' 表示 BUBBLESORT(A)的输出. 为了证明BUBBLESORT正确, 我们必须证明它将终止并且有:
A'[1]<=A'[2]<=...<=A'[n] (2.3)
其中n=A.length. 为了证明BUBBLESORT确实完成了排序,我们还需要证明什么?
下面两部分将证明不等式(2.3).
b.为2~4行的for循环精确地说明一个循环不变式,并证明该循环不变式成立.
你的证明应该使用本章中给出的循环不变式证明的结构
初始化:
首先证明在第一次迭代之前(当j=2时), 循环不变式成立.
所以对子数组A[A[2],...,A.length]进行排列
如果A[2]<A[1] 就交换A[2]和A[1] 这时 A[1]<=A[2]
保持:
如果A[j]<A[j-1] 就交换A[j]和A[j-1] 这时A[j-1]=A[j] A[j]为当前循环到的最大的数
终止:
在排列A.length-1次后 j=A.length 最后排列结果为: A[j-1]<=A[j] A[j]为整个A中最大的数
c. 使用(b)部分证明的循环不变时的终止条件,为第1~4行的for循环说明一个循环不变式,该不变式将使你能证明不等式(2.3).你的证明应该使用本章中给出的循环不变式证明的结构.
初始化:
首先证明i=1时,循环不变式成立
根据b得出的结果 i=1时找出了A.length中最大的数 放在A的最后
保持:
1<i<A.length-1, j = i+1
根据b得出的结论 剩余未找到最大数的数字有A.length-j个 对A.length-j个数找最大数 放在A.length-j个数的最后
循环完成后 有j个数是按照从小到大依次排列在A.length的最后部分的
终止:
当i = A.length-1,j = A.length时 循环不变式结束 所有数都按照从小到大依次排列完成
d.冒泡排序的最坏运行时间是多少?与插入排序的运行时间相比,其性能如何?
冒泡排序 对n个数进行排序
第一行i循环 执行时间(n-1)*c1
第二行j循环 执行时间(1+2+...+n-1)*c2
第三行比较 执行时间(1+2+...+n-1)*c3
第四行交换 执行时间(1+2+...+n-1)*c4
加起来运行时间是(n-1)*n/2*(c2+c3+c4)+(n-1)*c1
最坏运行时间θ(n^2) 与插入排序相比 其时间复杂度相同