算法设计与分析基础(十)

本文介绍了变治法,一种通过问题变形和实例化简来简化问题解决的策略。涉及预排序提升效率、二叉查找树的操作优化、堆排序与霍纳法则的应用,以及最小公倍数求解和图论路径计数的转换。通过实例展示了如何将复杂问题转化为更易处理的形式。
摘要由CSDN通过智能技术生成

算法设计与分析基础(十):变治法

  • 首先是“变”, 将问题变形, 转换成另一个问题,变得更容易求解;
  • 然后是“治”,对问题的实例进行求解。
  • 变治法有三个变形:
    (1)实例化简——同样问题
    (2)改变表现——同样实例
    (3)问题化简——另一问题

实例化简——同样问题

预排序

列表若有序,列表上的部分问题更容易求解。因此很多问题需要先排序,则该问题的时间效率依赖于排序算法的效率。
回忆前面所学的排序算法:

image-20211214161801275

例子:检验数组中元素的唯一性

Algorithm PEU (A[0..n-1])  // Presort Element Uniqueness
    //先对数组排序再验证唯一性
    //输入:数组A
    //输出:若A没有相等的元素,返回“true”,否则返回“false”.
    对数组排序; T:= true;
    for i=0 to n-2 do
             if A[i]=A[i+1]   then  T:= false;
 3.      return T.

改变表现——同样实例

集合上的操作–二叉查找树

把一个集合变换成 一棵二叉查找树是改变表现技术的一个实例。

好处是:在平均情况下,查找,插入,删除的效率是Θ(logn)。
最差情况下, Θ(n),退化成线性的情况。

所谓的二叉查找树,它或者是一棵空树,或者满足以下的性质:
每个结点作为搜索对象,它的关键字是互不相同的。
对于树上的所有结点,如果它有左子树,那么左子树上所有结点的关键字都小于该结点的关键字。
对于树上的所有结点,如果它有右子树,那么右子树上所有结点的关键字都大于该结点的关键字。

插入操作:(建树)

image-20211214162647571

删除操作:

对于二叉查找树的删除操作(这里根据值删除,而非结点)分三种情况:在此之前,我们应该确保根据给定的值找到了要删除的结点,如若没找到该结点不会执行删除操作!
下面三种情况假设已经找到了要删除的结点:

  1. 如果为叶子结点(没有左、右子树),此时删除该结点不会破坏树的结构,直接删除即可,并修改其父结点指向它的引用为null.如下图:

    image-20211214163055091

  2. 如果其结点只包含左子树,或者右子树的话,此时直接删除该结点,并将其左子树 或者右子树设置为其父结点的左子树或者右子树即可,此操作不会破坏树结构。

    image-20211214163129578

  3. 当结点的左右子树都不空的时候,一般的删除策略是用其右子树的最小数据(容易找到)代替要删除的结点数据并递归删除该结点(此时为null),因为右子树的最小结点不可能有左孩子,所以第二次删除较为容易。

    image-20211214163220920

    z的左子树和右子树均不空。找到z的后继y,因为y一定没有左子树,所以可以删除y,让y的父亲节点成为y的右子树的父亲节点,并用y的值代替z的值.如图:

    image-20211214163317795

堆和堆排序

设T是一棵深度为d的二叉树,结点为L中的元素.
若满足:

  • 所有内结点(可能一点除外)的度数为2
  • 所有树叶至多在相邻的两层
  • d-1层的所有树叶在内结点的右边
  • d-1层最右边的内结点可能度数为1 (没有
    右儿子)
  • 每个结点的元素不小于儿子的元素
自底向上构造法

首先把数组按序填充到堆中各个结点然后按照自下而上,从右至左的顺序,从最后的父节点开始,到根为止,检查

这些节点的值是否都满足子结点比父结点小的约束条件。

如果不满足则调换父子结点的位置,然后再检查在新的位置上,是否满足父母优势要求。

image-20211214164821211

复杂度分析:

结点的高度 该结点距树叶的距离
结点的深度 该结点距树根的距离
同一深度结点分布在树的同一层,同一高度结点可以分布在树的不同的层
思路:
HEAPIFY(i)的复杂度依赖于i的高度,按照高度计数结点数,乘以O(h),再求和

image-20211214164937877

堆排序
算法HEAPSORT(A)
1. BUILD-H EAP(A)
2. for i< - length[A] downto 2 .
3. do exchange A[1]< >A[i]
4.heap-size[4] < -heap-size[4]-1
5.HEAPIFY(A,1)

复杂性: O(mlogn)
BUILD_ HEAP时间为O(n),从行2-5调用HEAPIFY 1-1次,每次O(logn),时间为O(nlogn)

Horner法则和二进制幂

Horner法则

计算n次多项式的值的算法。
例如,n=4,
直接计算,需要4+3+2+1=10=n(n-1)/2次乘法。用如下Horner/秦九韶算法只需要 n=4 次乘法;

image-20211214165448773

当 x=3 时,计算 p(x)

系数2-131-5
X=322×3+(-1)=55×3+3=1818×3+1=5555×3+(-5)=160

霍纳法则的有趣特性

该算法在计算p(x)在某些点 x0上的值所产生的中间数字恰好可以作为 p(x)除以 x- x0 的商的系数,而算法的最后结果( p(x0)的值),等于这个除法的余数。

原理如下: 对任意的f(x)与g(x),存在q(x)与 r(x),使得
f(x) = q(x)g(x) + r(x)
表示 g(x) 除 f(x), 商为q(x), 余数为 r(x),因此,
p(x) = q(x)(x- x0) + r, p(x0) = q(x0)(x0 - x0) + r, p(x0) = r .

image-20211214165654115

二进制幂

计算an的算法,有两种方法:

从左到右逐位扫描算法:例求a13, 13=1101

若该位为1,则前一个数平方后再乘以a,否则不需要再乘

image-20211214171836651

从右到左逐位扫描算法:例如 求a13, 13=1101

若该位为0,中间结果相乘时候不相乘

image-20211214171257809

问题化简——另一问题

求最小公倍数lcm(m, n)

原问题:
求能够被m和n整除的最小整数记为lcm(m, n)
常用算法:
m和n所有公共质因数乘以m的不在n中的质因数,再乘以n不在m中的质因数
24=2×2×2×3 60=2×2×3×5
lcm(24, 60)=(2×2×3)×2×5=120
缺陷:
需要连续素数的表

关联
m和n的最大公约数gcd(m,n)是m和n所有公共质因子的积。并且lcm(m,n) = m·n/gcd(m,n)

问题化简
转换为求最大公约数gcd(m,n)的高效的欧几里德算法

计算图中的路径数

原问题: 计算无向无权图中两个顶点之间的路径数量
问题化简: 利用邻接矩阵,可以证明:
图 G 中顶点 vi 到顶点 vj 之间长度为 k 的路径数量等于Ak 的 (i, j)位置的元素,其中 A 是图 G 的邻接矩阵。

image-20211214172328984

简化为图论问题

过河问题:一个农夫希望用一条小船把一只狼,一头羊,一篮白菜从河的北岸渡到河的南岸,由于船小只能够容纳人狼羊菜中的两个。需要考虑的约束条件是:在没有人的情况下,狼和羊不能在一起,羊和白菜不能单独在一起。求解一个渡船的方案,把狼、羊、白菜都运过去。

对过河问题,画出人、狼、羊、菜的状态空间图后即可以发现有两条路径,这两条路径就是问题的两个解。

解:用四维0-1向量表示(人,狼,羊,菜)在河西岸的状态(在河西岸则分量取1,否则取0),共有24 =16 种状态.在河东岸的状态类似记作.
由题设,状态(0,1,1,0),(0,0,1,1),(0,1,1,1)是不允许的,从而对应状态(1,0,0,1), (1,1,0,0), (1,0,0,0)也是不允许的.
以可允许的10个状态向量作为顶点,将可能互相转移的状态用线段连接起来构成一个图.
根据此图便可找到渡河方法.

image-20211214172546720

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值