算法导论 2-2

本文详细介绍了冒泡排序算法的工作原理、正确性证明以及与插入排序的性能比较。通过逐步分析,揭示了算法的循环不变式和终止条件,最终证明了算法的有效性和效率。此外,文章还探讨了冒泡排序在实际应用中的局限性及改进策略。
摘要由CSDN通过智能技术生成

题目

冒泡排序(bubblesort)算法是一种流行的排序算法,它重复地交换相邻的两个反序元素。
  1. BUBBLE-SORT(A)
  2.     for i <- 1 to length(A)
  3.         do for j <- length(A) downto i+1
  4.                  do if A[j] < A[j-1]
  5.                        then exchange A[j] <-> A[j-1]
a)设A'表示BUBBLESORT(A)的输出。为了证明BUBBLESORT是正确的,需要证明它能够终止, 并且有:
A'[1]<=A'[2]<=...<=A'[n]
其中n=length[A]。为了证明BUBBLESORT的确能实现排序的效果,还需要证明什么?
b)对于第3~5行中的for循环,给出一个准确的循环不变式,并证明该循环不变式是成立 的。在证明中采用本章给出的循环不变式证明结构。
c)利用在b)中证明的循环不变式的终止条件,为第2~5行中的for循环给出一个循环不变 式,它可以用来证明a)中的不等式。你的证明应采用本章中给出的循环不变式的证明结 构。
d)冒泡排序算法的最坏情况运行时间是什么?比较它与插入排序的运行时间。

分析

问题a

还需要证明A'是A的一个排列。

问题b

循环不变式:在循环的每次迭代开始前,A[j]为子数组A[j...n]中的最小元素,并且 A[j...n]是原A[j...n]的一个排列。
初始化:在循环的第一次迭代开始前,j=n,A[j...n]=A[n]只有一个元素,显然A[n]是 A[n]中最小的元素,并且A[n]就是A[n]的一个排列。循环不变式成立。
保持:假设在循环的某次迭代开始前,循环不变式成立。此时j=k,根据循环不变式, A[j]=A[k]为A[j...n]=A[k...n]中的最小元素,并且A[k...n]是原A[k...n]的一个排列。 执行此次迭代,设A[k]=p,A[k-1]=q,如果第四行的判断为真,那么A[k] < A[k-1],因为A[k]是A[k...n]中 的最小值,而A[k]比A[k-1]小,所以p是A[k-1...n]中的最小值;当A[k]与A[k-1]交 换后,交换后A[k-1...n]从[q,p,A[k+1...n]]变为 [p,q,A[k+1...n]],所以A[k-1]为A[k-1...n]中的最小值;又因为A[k...n]是原A[k...n]的一个排列,所以A[k+1...n]包含了除 p外的所有原A[k...n]的所有元素,而A[k-1...n]包含了p,q和A[k...n]中除p外的所有 元素,所以交换后A[k-1...n]包含了原A[k-1...n]的所有 元素,是原A[k-1]的一个排列。
如果第4行的判断为假,说明A[k-1]小于等于A[k...n]中的任何元素,所以A[k-1]为 A[k-1...n]中最小的元素;又因为A[k...n]是原A[k...n]的一个排列,即A[k...n]包含 原A[k..n]的所有元素,而A[k-1...n]包 含A[k-1]和A[k...n]中的所有元素,是原A[k-1...n]的一个排列
当下一次迭代开始前,此时j=k-1,由上面的分析可知,A[k-1]为A[k-1...n]的最小值, 并且A[k-1...n]为原A[k-1...n]的一个排列。
终止:当迭代终止时,此时j=i,从保持的分析可知,A[i]是A[i...n]的最小值,并且 A[i...n]是原A[i...n]的一个排列。

问题c

循环不变式:在循环的每次迭代开始前,子数组A[1...i-1]保存着A[1...n]中最小的 i-1个数,并且是已经排序好的。
初始化:在循环的第一次迭代开始前,i=1,A[1...0]不包含任何元 素,可以规定空数组比任何非空数组中的元素都小,循环不变式成立;
保持:假设在循环的某次迭代开始前,循环不变式成立。此时i=k, A[1...k-1]包含已排序的A[1...n]中最小的k-1个元素。执行此次迭代,由问题b的终止 条件得知,A[i]=A[k]为A[k...n]中的最小值,有因为A[k]大于等于A[1...k-1]中的任 一元素,所以A[1...k]为已排序的A[1...n]中最小的k个元素,那么在下次迭代开始前, 此时i=k+1,循环不变式也成立;
终止:当循环终止时,i=n+1,由循环不变式的值,A[1...n]是 A[1...n]中已排序的最小的n个数,而A[1...n]包含了原来A[1...n]中的所有元素,因 此整个数组已经排序好,这意味着算法正确。

问题d

显然冒泡排序的运行时间由外层和内层循环次数决定,内层每次运行n-i次,所以冒泡 排序总的运行次数为 = ,与插 入排序相同。

伪代码

# BUBBLE-SORT(A)
# for i <- 1 to length(A)
#     do for j <- length(A) downto i+1
#            do if A[j] < A[j-1]
#               then exchange A[j] <-> A[j-1]

Python代码实现

def bubble_sort(a, p, r):
    for i in range (p, r+1):
        for j in range(r, i, -1):
            if a[j] < a[j-1]:
                temp = a[j]
                a[j] = a[j-1]
                a[j-1] = temp


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值