算法设计与分析-减治法1

这篇文章将讨论:

1) 减治法的思想和策略

2)  几个数据结构里面经典的使用减治策略的算法:插入排序,深度和广度优先查找,拓扑排序(都是减一治的)

通过 1) 2)明白减治策略的基本思想和方法,也对经典数据结构做一番新的审视,从减治策略的角度来重新看待这些算法。

而在后面,将继续花几篇文章讨论减治策略的其他问题:排列问题,子集问题,减常因子算法,减可变规模算法。

----------------------------------------------------------------------------------------------------------------------------------------------------


减治技术利用了一个问题给定实例的解和同样问题较小实例的解之间的某种关系。一旦建立了这种关系,就可以从顶至下递归的来用该关系,也可以从底至上非递归的来运用该关系

1)减去一个常量

2)减去一个常量因子

3)减去的规模是可变的


1)   一般来说减去的一个常量是1,即如果不断地解决n-1规模的问题就能解决n规模的问题,(偶而也有减2的,比较少)

比如求a^n的值,



既可以递归的从上到下求解,也可以非递归的从下往上构造(连续乘法,注意方法和蛮力一样,但思考问题的角度不一样)



2)  一般来说减去的一个常数因子是2(即将原问题规模分为2),其实减常因子的减治法可以看做是分治的变种,只不过它只对划分子规模后的一个部分求解。

例如仍然是求a^n,我们可以这样来思考:





3)对于减可变规模的例子,那就更少了,因为效率越高的算法显然越难找到。

一个例子是欧几里得算法,前面也写过了:




总之,减治的3种方法,以及一个简单的例子就像上面所述。


-------------------------------------------------------------------------------------------------------------------------------------------------


1,插入排序


1)  最简单的排序方法,写过,也很简单。说下怎么从减一治的策略来思考:

对A[0...n-1]排序,如果你已经对0到n-2排好了序,那么将n-1号插入到合适的位置即可(注意后面的要移动)

这就递归的定义了插入排序的过程,当然,一般从底向上非递归的构造效率更高。递归和非递归的版本都可以写,略过。


2)简单的扩展下:折半插入排序,在一个元素要求插入时,在寻找它的插入位置时,用折半查找来寻找,复杂度是nlogn


3)shell排序:插入排序的改进,递减插入步长,比如分别以13,4,1为步长来插入排序。

有机会写一下。由于它的步长原因,可以看出shell排序是不稳定的。(插入排序是稳定的,它的步长是1)


-------------------------------------------------------------------------------------------------------------------------------------------------


2,深度优先查找和广度优先查找



1)深度优先查找

更正:前面写的深度优先查找是错误的,那本书上讲的也是错误的。见前面的文章,我已经确认过了。

那本书上是这样写的:

初始化:第一个顶点入栈
while(栈不空)

{

  将当前栈顶元素出栈
  将出栈的这个顶点的所有未被访问的邻接点入栈

}

其结果是把出栈的顺序作为深度优先遍历的结果,错错错!!!!!!!!!!!!!!!!!!!

这是形式上完全照抄广度优先遍历的写法,广度优先遍历这样是对的(把栈改成队列,形式完全一样) 。它这样做的核心思想似乎是每个顶点出栈时要把它未被访问的邻接点入栈,似乎这样就能导致一个顶点扩展出去的顶点全部访问完才能回到跟它同一批入栈的下一个顶点,事实上,大错特错!!!!!

错误:

a  不要把出栈顺序当做访问顺序,而 应该把进栈顺序当做访问顺序 ,重写一个程序(见下面)

b   不要冒然出栈 ,只有当一个顶点是死端(它没有邻接点或邻接点已经都被访问过了)了,才将它出栈。

c  出栈时 不是将它所有的顶点都入栈 ,而是 仅仅将它的一个 未被访问的顶点入栈。



其正确的算法是这样的:(用栈来实现)


初始化:第一个顶点入栈
while(栈不空)

{

  检查当前栈顶元素是否为死端

  if(栈顶元素是死端)

    出栈;

  else(不是死端)

    把它的一个未被访问的邻接点入栈;

}


妈的,害我错误了这么久。

当然,递归的来定义会简单很多,不管什么死端不死端,直接递归的定义深度优先搜索,略。


另外一点就是这里又扩展了一点,树向边和回边:



进栈顺序(第一个下标):  a  c  d  f  b  e      g  h  i  j  (深度遍历被访问顺序)

出栈顺序(第二个下标):  d  e  b  f  c  a  |  j  i  h  g

树向边:在检查栈顶A时,若A不是死端,那么将A的一个未被访问的邻接点B入栈,这就有了树向边A-B

回边:若检查栈顶A时,A是死端,则A到它的非父节点的邻接点之间就存在一个回边。

见上图。

不含回边----无回路



2)广度优先查找

那本书上是对的,跟上述深度的错误代码一样,只是将栈改成队列。

也有树向边和回边。

不再详述。

BFS可以用来求2个顶点之间的最短距离,从其中一个开始遍历,当到达另一个时就停止,此时BFS树的根到第二个顶点之间的路径具有最小边数:




最后,一个总结:






-------------------------------------------------------------------------------------------------------------------------------------------------



3,拓扑排序

1)  从减一治的角度,其实就是传统的拓扑算法,就是每次从图中删除一个入度为0的顶点,见前面的一篇文章,很easy。


2)  来说一点有意思的,深度优先遍历中出栈的顺序反过来就是拓扑序列。请思考一下。







------------------------------------------------------------------------------------------------------------------------------------------------


总结:

减一治的思想和3种策略

3种经典的数据结构算法,从减一治的角度思考。

特别是深度优先的更正!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法设计与分析 作者-王红梅 出版社-清华大学出版社 出版日期-07 1 2006. 共262页 目录 第 1 章 绪论 1 .1 算法的基本概念 1 . 1 . 1 为什么要学习算法 1 . 1 . 2 算法及其重要特性 1 . 1 . 3 算法的描述方法 1 . 1 . 4 算法设计的一般过程 1 . 1 . 5 重要的问题类型 1 .2 算法分析 1 . 2 . 1 渐进符号 1 . 2 . 2 最好、 最坏和平均情况 1 . 2 . 3 非递归算法的分析 1 . 2 . 4 递归算法的分析 1 . 2 . 5 算法的后验分析 1 .3 实验项目— — —求最大公约数 阅读材料— — —人工神经网络与 BP 算法 习题 1 第 2 章 NP 完全理论 2 .1 下界 2 . 1 . 1 平凡下界 2 . 1 . 2 判定树模型 2 . 1 . 3 最优算法 2 .2 算法的极限 2 . 2 . 1 易解问题与难解问题 2 . 2 . 2 实际问题难以求解的原因 2 . 2 . 3 不可解问题 2 .3 P 类问题和 NP 类问题 2 .3 .1 判定问题 2 .3 .2 确定性算法与 P 类问题 2 .3 .3 非确定性算法与 NP 类问题 2 .4 NP 完全问题 2 .4 .1 问题变换与计算复杂性归约 2 .4 .2 NP 完全问题的定义 2 .4 .3 基本的 NP 完全问题 2 .4 .4 NP 完全问题的计算机处理 2 .5 实验项目— — —SAT 问题 阅读材料— — —遗传算法 习题 2 第 3 章 蛮力法 3 .1 蛮力法的设计思想 3 .2 查找问题中的蛮力法 3 .2 .1 顺序查找 3 .2 .2 串匹配问题 3 .3 排序问题中的蛮力法 3 .3 .1 选择排序 3 .3 .2 起泡排序 3 .4 组合问题中的蛮力法 3 .4 .1 生成排列对象 3 .4 .2 生成子集 3 .4 .3 0 / 1 背包问题 3 .4 .4 任务分配问题 3 .5 图问题中的蛮力法 3 .5 .1 哈密顿回路问题 3 .5 .2 TSP 问题 3 .6 几何问题中的蛮力法 3 .6 .1 最近对问题 3 .6 .2 凸包问题 3 .7 实验项目— — —串匹配问题 阅读材料— — —蚁群算法 习题 3 第 4 章 分治法 4 .1 概述 4 .1 .1 分治法的设计思想 4 .1 .2 分治法的求解过程 4 .2 递归 4 .2 .1 递归的定义 4 .2 .2 递归函数的运行轨迹 4 .2 .3 递归函数的内部执行过程 4 .3 排序问题中的分治法 4 .3 .1 归并排序 4 .3 .2 快速排序 4 .4 组合问题中的分治法 4 .4 .1 最大子段和问题 4 .4 .2 棋盘覆盖问题 4 .4 .3 循环赛日程安排问题 4 .5 几何问题中的分治法 4 .5 .1 最近对问题 4 .5 .2 凸包问题 4 .6 实验项目— — —最近对问题 阅读材料— — —鱼群算法 习题 4 第 5 章 治法 5 .1 治法的设计思想 5 .2 查找问题中的治法 5 .3 排序问题中的治法 5 .4 组合问题中的治法 5 .5 实验项目— — —8 枚硬币问题 阅读材料— — —粒子群算法 习题 5 第 6 章 动态规划法 6 .1 概述 6 .2 图问题中的动态规划法 6 .3 组合问题中的动态规划法 6 .4 查找问题中的动态规划法 6 .5 实验项目— — —最大子段和问题 阅读材料— — —文化算法 习题 6 第 7 章 贪心法 7 .1 概述 7 .2 图问题中的贪心法 7 .3 组合问题中的贪心法 7 .4 实验项目— — —霍夫曼编码 阅读材料— — —模拟退火算法 习题 7 第 8 章 回溯法 8 .1 概述 8 .2 图问题中的回溯法 8 .3 组合问题中的回溯法 8 .4 实验项目— — —0/ 1 背包问题 阅读材料— — —禁忌搜索算法 习题 8 第 9 章 分支限界法 9 .1 概述 9 .2 图问题中的分支限界法 9 .3 组合问题中的分支限界法 9 .4 实验项目— — —电路布线问题 阅读材料— — —免疫算法 习题 9 第 10 章 概率算法 10 .1 概述 10 .1 .1 概率算法的设计思想 10 .1 .2 随机数发生器 10 .2 舍伍德(Sherwood)型概率算法 10 .2 .1 快速排序 10 .2 .2 选择问题 10 .3 拉斯维加斯( Las Vegas)型概率算法 10 .3 .1 八皇后问题 10 .3 .2 整数因子分解问题 10 .4 蒙特卡罗(Monte Ca rlo)型概率算法 10 .4 .1 主元素问题 10 .4 .2 素数测试问题 10 .5 实验项目— — —随机数发生器 阅读材料— — —DNA 计算与 DNA 计算机 习题 10 第 11 章 近似算法 11 .1 概述 11 .1 .1 近似算法的设计思想 11 .1 .2 近似算法的性能 11 .2 图问题中的近似算法 11 .2 .1 顶点覆盖问题 11 .2 .2 TSP 问题 11 .3 组合问题中的近似算法 11 .3 .1 装箱问题 11 .3 .2 子集和问题 11 .4 实验项目— — —TSP 问题的近似算法 阅读材料— — —量子密码技术 习题 11 第 12 章 计算复杂性理论 12 .1 计算模型 12 .1 .1 图灵机的基本模型 12 .1 .2 k 带图灵机和时间复杂性 12 .1 .3 离线图灵机和空间复杂性 12 .2 P 类问题和 NP 类问题 12 .2 .1 非确定性图灵机 12 .2 .2 P 类语言和 NP 类语言 12 .3 NP 完全问题 12 .3 .1 多项式时间变换 12 .3 .2 Cook 定理 12 .4 实验项目— — —NP 完全问题树 阅读材料— — —算法优化策略

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值