算法分析——第四章复习:分治法

分治法


一、一般方法

分治法的三个步骤:
  • 分解(Divide,分):将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小;
  • 解决(conquer,治):递归求解出子问题。如果子问题的规模足够小,则停止递归,直接求解;
  • 合并(combine,合):将子问题的解组合成原问题的解。

二、分治法的应用——二分检索(折半查找、BINSRCH)

二分检索——是采用分治法来解决有序表的排列问题。

问题描述:
  • 已知一个按非降序排列的元素表
    a 1 ≤ a 2 ≤ … ≤ a n a_1≤a_2 ≤ … ≤ a_n a1a2an
  • 给定元素x
    判断x是否在该表中出现
  • 若是, 则找出该元素在表中的位置,并将下标值赋给j
    否则置j为0
二分检索原理:
  • 将二分检索问题表示为: I = ( n , a 1 , … , a n , x ) I=(n, a_1, … , a_n, x) I=(n,a1,,an,x)
    即从包含n个元素的非降序排列元素表中检索元素 x x x
  • 选取一个下标k,可得到三个子问题:
    I 1 = ( k − 1 , a 1 , … , a k − 1 , x ) I_1=(k-1, a_1, … , a_{k-1}, x) I1=(k1,a1,,ak1,x)
    I 2 = ( 1 , a k , x ) I_2=(1, a_k , x) I2=(1,ak,x)
    I 3 = ( n − k , a k + 1 , … , a n , x ) I_3=(n-k, a_{k+1}, … , a_n, x) I3=(nk,ak+1,,an,x)
  • 对所求解的问题(或子问题)所选的下标都是
    中间元素的下标, k = ⌊ ( n + 1 ) / 2 ⌋ k= \left\lfloor(n+1)/2\right\rfloor k=(n+1)/2
二分检索算法(伪代码描述):

二分检索算法

二分检索实例:

设在A(1:9)中顺序放了一下九个元素:
实例01
实例02

二分检索算法所需的空间与时间
1.所需空间:
  • 用n个位置存放数组A
  • 还有low, high, mid, x, j五个变量需要存储
    共需空间 n+5
2.所需时间:

对于计算时间,我们需要考虑一下情况:

  • 成功检索的最好情况、平均情况、最坏情况
  • 不成功检索的最好情况、平均情况、最坏情况

成功检索一共有n种情况,不成功检索有n+1种情况

在这里插入图片描述
例如在上面的实例中,成功检索的情况有9种,不成功的有10种。

成功检索的三种情况(即在数组A中找到x):

  • 最好情况:用最少的比较找到x的情况。
  • 最坏情况:用最多的比较找到x情况。
  • 平均情况:成功情况中的所有情况都考虑。

同理,不成功检索也有三种情况。


针对上面的实例,我们利用二分检索对应的二元比较树来计算所需的时间。
二元比较树

该二元比较树有9个内节点,由 2 3 ≦   9 ≦   2 4 2^3\leqq\ 9 \leqq\ 2^4 23 9 24,树的高度为4。

由二分检索对应的二元比较树可知,

  • 成功检索的最好情况比较1次。
    成功检索的最坏情况比较4次。
    成功检索的平均情况为 3 + 2 + 3 + 4 + 1 + 3 + 2 + 3 + 4 9 = 2.7777 … … \frac{3+2+3+4+1+3+2+3+4}{9}=2.7777…… 93+2+3+4+1+3+2+3+4=2.7777
  • 不成功检索的最好情况比较3次。
    不成功检索的最坏情况比较4次。
    不成功检索的平均情况为 3 + 3 + 3 + 4 + 4 + 3 + 3 + 3 + 4 + 4 10 = 3.4 \frac{3+3+3+4+4+3+3+3+4+4}{10}=3.4 103+3+3+4+4+3+3+3+4+4=3.4

于是二分检索BINSRCH算法的时间复杂度为:
二分检索的时间复杂度
另一种算法的实现:

对于之前给出的算法,while循环中的代码块如下:
在这里插入图片描述
在BINSRCH程序的While循环中,case语句可能要做两次比较;

于是我们给出每次循环固定比较一次的二分检索算法。

在这里插入图片描述

实例分析:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

三、分治法的应用——归并排序(合并排序、MERGESORT)

问题描述:

给定一个含有n个元素的集合,对其进行排序(如非降次序)

归并排序的基本思想:

(1)将待排序元素分成大致相同的两个子集合
(2)分别对两个子集合进行排序
(3)将排好序的两个子集合并成一个排好序的集合

归并排序的算法伪代码描述:

在这里插入图片描述
在这里插入图片描述

归并排序的执行过程:

在这里插入图片描述

归并排序的计算时间:

考虑Merge算法,合并两个数组所需的比较次数。
假设两个数组长度都为k,总长度为n,最好情况下比较 k k k (也就是 n 2 \frac {n} {2} 2n) 次,最坏情况下比较 2 k + 1 2k+1 2k+1(也就是 n − 1 n-1 n1)次。

因此归并排序的计算时间:

在这里插入图片描述
n = 2 k n=2^k n=2k时,可得
T ( n ) = 2 ( 2 T ( n 4 ) + c n 2 ) + c n = 2 2 T ( n 4 ) + 2 c n = 2 2 ( 2 T ( n 8 ) + c n 4 ) + 2 c n = 2 3 T ( n 8 ) + 3 c n … … = 2 k T ( 1 ) + k c n = a n + c n l o g n T(n)=2(2T(\frac {n}{4})+c\frac{n}{2})+cn\\ \qquad = 2^2T(\frac{n}{4})+2cn\\ \qquad = 2^2(2T(\frac{n}{8})+c\frac{n}{4})+2cn\\ \qquad = 2^3T(\frac{n}{8})+3cn\\ \qquad ……\\ \qquad = 2^kT(1)+kcn\\ \qquad = an+cnlogn T(n)=2(2T(4n)+c2n)+cn=22T(4n)+2cn=22(2T(8n)+c4n)+2cn=23T(8n)+3cn=2kT(1)+kcn=an+cnlogn

最终得到 T ( n ) = O ( n l o g n ) T(n)=\Omicron(nlogn) T(n)=O(nlogn)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Desperado1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值