算法导论 2.3-5

题目

回顾一下联系2.1-3中提到的查找问题,注意如果序列A是已排序的,就可以将该序列的中点与v进行比较。根据比较的结果,原序列中有一半就可以不用再做进一步的考虑了。二分查找就是一个不断重复这一过程的算法。写出二分查找的伪代码,可以是迭代的,也可以是递归的。说明二分查找的最坏情况运行时间是为什么是

分析

分别给出迭代形式和递归形式的分析,从分析可以看出迭代和递归是等价的,递归的解法比较直观,迭代的空间代价是较小的。

迭代形式分析

给定参数A,p,r,v,A[p...r]是排序好的序列。需要一个变量q记录中点的位置,然 后就是迭代的循环:
q被赋值为
v==A[q],找到了v,返回q值;
v>A[q],p被赋值为q+1;
v<A[q],r被赋值为q-1;
循环的终止条件是p<=r。 这里必须有等号,否则对于单个数据的数组没法查找了
试着写出迭代的二分查找的循环不变式:在循环的每次迭代开始前,必然满足不等式A[p]<=v或A[r]>=v,且是排序好的。

伪代码

BINARY-SEARCH-ITERATION(A, p, r, v)costtimes
if A[p] > v or A[r] < vc11
    then return NILc21或0
while p <= rc3ti
    q <- c4ti-1
    if v == A[q]
        then return q
    else if v > A[q]
                 then p <- q+1
             else r <- q-1
c5ti-1
                
    if A[p] > v or A[r] < v
c6ti-1
        then return NILc71或0
return NILc81

为满足循环不变式,加入对断点的判断

时间复杂度分析

由伪代码的分析可以看出,整个程序的运行时间由ti决定,所以, ,而在最坏情况下,即v与A[p]或A[r]相等,由于每次搜索范围都是上一次的一半,所以此种情况下,while循环运行 次,因此


递归形式分析

伪代码

BINARY-SEARCH-RECURSION(A, p, r, v)
1    if p <= r
2        then q <- 
3                  if A[q] == v
4                      then return q
5                      else if A[q] > v
6                                   then return BINARY-SEARCH-RECURSION(A, p, q-1, v)
7                                   else return BINARY-SEARCH-RECURSION(A, q+1, r, v)
8    retrun NIL

时间复杂度分析

使用分治法分析:
分解:这一步需要求出中点的位置,并进行比较,步骤是常数,因此
解决:递归的解决规模为n/2的子问题,所以时间为T(n/2)
合并:显然,二分查找直接返回v的位置,不需要合并,因此C(n)=0
因此,二分查找的递归式为

通过画出递归树或主定理都可以得到二分查找的最坏运行时间为

Pyhton实现

迭代

def binary_search_ite(a, p, r, v):
    if a[p] > v or a[r] < v:
        return None
    while p <= r:
        q = (p + r) / 2
        if a[q] == v:
            return q
        elif a[q] > v:
            r = q - 1
        elif a[q] < v:
            p = q + 1
        if a[p] > v or a[r] < v:
            return None
    return None


递归

def binary_search(a, p, r, v):
    if p <= r:
        q = (p + r) / 2
        if a[q] == v:
            return q
        elif a[q] > v:
            return binary_search(a, p, q-1, v)
        elif a[q] < v:
            return binary_search(a, q + 1, r, v)
    return None




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值