算法导论 2.3-5
来源:互联网 发布:网络直播乱象丛生 编辑:程序博客网 时间:2024/05/16 10:47
题目
回顾一下联系2.1-3中提到的查找问题,注意如果序列A是已排序的,就可以将该序列的中点与v进行比较。根据比较的结果,原序列中有一半就可以不用再做进一步的考虑了。二分查找就是一个不断重复这一过程的算法。写出二分查找的伪代码,可以是迭代的,也可以是递归的。说明二分查找的最坏情况运行时间是为什么是
分析
分别给出迭代形式和递归形式的分析,从分析可以看出迭代和递归是等价的,递归的解法比较直观,迭代的空间代价是较小的。
迭代形式分析
给定参数A,p,r,v,A[p...r]是排序好的序列。需要一个变量q记录中点的位置,然 后就是迭代的循环:
q被赋值为
试着写出迭代的二分查找的循环不变式:在循环的每次迭代开始前,必然满足不等式A[p]<=v或A[r]>=v,且是排序好的。
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)costtimesif A[p] > v or A[r] < vc11 then return NILc21或0while p <= rc3ti q <- c4ti-1 if v == A[q]
then return q
else if v > A[q]
then p <- q+1
else r <- q-1c5ti-1
if A[p] > v or A[r] < vc6ti-1 then return NILc71或0return NILc81
为满足循环不变式,加入对断点的判断
then return q
else if v > A[q]
then p <- q+1
else r <- q-1c5ti-1
if A[p] > v or A[r] < vc6ti-1 then return NILc71或0return 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)
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
因此,二分查找的递归式为
通过画出递归树或主定理都可以得到二分查找的最坏运行时间为
分解:这一步需要求出中点的位置,并进行比较,步骤是常数,因此
解决:递归的解决规模为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.3-5
- 算法导论 练习 2.3-5
- 算法导论2.3-5二分查找
- 算法导论2.3-5二分法查找问题
- 算法导论 2.3-7
- 算法导论 2.3-2
- 算法导论 2.3-3
- 算法导论 2.3-4
- 算法导论 2.3-7
- 算法导论2.3-6
- 算法导论2.3.7
- 算法导论2.3.7
- 算法导论2.3-7
- 算法导论7.4-5
- 算法导论 3.1-5
- 算法导论 3.2-5
- 算法导论 3-5
- 算法导论 4.1-5
- iOS 项目改名
- 组成Spring框架的7个模块
- JMVC变量命名规则
- C下如何实现printf在同一行打印,如安装程序进程显示
- 如何减少浏览器的repaint和reflow?
- 算法导论 2.3-5
- cocos2d-x 触屏事件
- for循环问题
- GNU Profiler (gprof) 的简单使用
- Java 仿C# delegate
- python中的参数定义与可变参数
- 在适合自己的地方闪光
- C#中方法重载与方法重写区别
- Java编程之对象序列化解析