算法与数据结构-分治法及汉诺塔问题求解
来源:互联网 发布:软件开放平台 编辑:程序博客网 时间:2024/06/06 19:48
序言
学习五大常用算法:回溯 + 贪心 + DP + 分治 + 分支界限
这里看分治法的概念及应用,并用汉诺塔问题举例
1. 分治法的概念及应用领域
分治法:
分而治之:将问题分解为相互独立的与原问题相同或相似的子问题,直到最后子问题可以直接求解,原问题的解即为子问题解的合并。
在之前复习常见排序算法的时候我们就已经用过这种算法了,快排、归并排序中,都有类似的子问题划分求解合并的过程。
分治策略:
- 一般来说,问题求解难度随着问题规模的增加而增加。对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。
- 要点:最优子结构性质 + 子问题相互独立
能用分治法求解的问题四个特征:
- 问题规模缩小至一定规模就可解决(大多数问题都可以满足)
- 问题可分解为多个规模较小的相同子问题(最优子结构性质,分治法的前提)
- 子问题的解可以合并为原问题的解(区别于贪心和动态规划)
- 该问题分解的子问题是相互独立的(分治法的效率,避免重复求解)
三个步骤
- 分解(Divide):将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题
- 解决(Conquer):若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
- 合并(Combine):将各个子问题的解合并为原问题的解
分治法求解的经典问题
- 二分查找
- 快排
- 归并排序
- 汉诺塔
- 大整数乘法
- Strassen矩阵乘法
- 棋盘覆盖
- 线性时间选择
- 循环赛日程表
2. 汉诺塔问题求解
问题描述
在汉诺塔游戏中,有三个分别命名为A、B、C得塔座,几个大小各不相同,从小到大一次编号得圆盘,每个原盘中间有一个小孔。最初,所有得圆盘都在A塔座上,其中最大得圆盘在最下面,然后是第二大,以此类推
游戏规则
- 一次只能移动一个圆盘
- 任何时候都不能将一个较大的圆盘压在较小的圆盘上面
- 除了第二条限制,任何塔座的最上面的圆盘都可以移动到其他塔座上
问题分析
现有三根柱子,我们分别称为 1柱,2柱,3柱.欲将1柱上的n个盘子移到3柱上: >> 把1柱n-1个盘子移到过2柱上(借助3柱为过渡柱) >> 把1柱上第n个盘子移到3柱 >> 将2柱的n-1个盘子移至3柱(借助1柱为过渡柱)到第三步我们发现,已经开始重复之前的过程,每次的目的都是将源柱盘子中最底端最大的盘子移动到目标柱上。呈现出递归的特点。总结一般规律: (1) 3个盘子的时候移动过程:1->3, 1->2,3->2,1->3,2->1,2->3,1->3. 一共7步完成移动。 (2) 如果是4个盘子,将上方3个盘子由1柱移动到2柱,需要7步,将第4个盘子移动到3柱上,需要1步,最后又将2柱上的3个盘子移动到3柱上,由(1)可知,也需要7步。一共需要:7+1+7=15步 (3) 如果是5个盘子,将上方4个盘子由1柱移动到2柱,需要15步,将第5个盘子移动到3柱上,需要1步,最后又将2柱上的4个盘子移动到3柱上,也需要15步。一共需要:15+1+15=31步 (4) 如果是6个盘子,...,一共需要:31+1+31=63步 一般规律是移动n个盘子,需要 2^n - 1 步。
- 代码实现-<递归,C语言>
#include <stdio.h>int i;void HanNuoTa(int n, char src, char trans, char dest){ if (n == 1) //n==1,直接将盘子从源柱移动到目标柱即可 printf("第%d步:将第%d个盘子从%c--->%c\n",i++, n, src, dest); else { HanNuoTa(n - 1, src, trans, dest); //先将n-1盘子移动到过渡柱 printf("第%d步:将第%d个盘子从%c--->%c\n",i++, n, src, dest); //将第n个盘子移动到目标柱 HanNuoTa(n - 1, trans, src, dest); //重复以上步骤,以源柱为过渡柱 }}int main(){ int n; while (scanf("%d", &n)) //scanf()成功返回读取的数据项数,文件尾返回NULL { i = 1; HanNuoTa(n, '1','2','3'); printf("总的步数%d\n", --i); } //或HanNuoTa(n, "1柱", "2柱", "3柱");函数原型为HanNuoTa(int n, char *src, char *trans, char *dest); return 0;}
Acknowledgements:
http://www.cnblogs.com/xsyfl/p/6921687.html
http://blog.csdn.net/geekwangminli/article/details/7981570 (推荐)
http://www.cnblogs.com/AI-Algorithms/p/3357368.html
2017.09.21
阅读全文
0 0
- 算法与数据结构-分治法及汉诺塔问题求解
- 算法与数据结构-回溯法及八皇后问题求解
- 数据结构与算法:分治法应用总结
- 【算法学习】最大子数组问题的分治法求解
- 分治算法求解kth largest element问题
- 求解最大值与最小值-分治算法
- 计算机算法设计与分析作业01:分治法求解大数乘法+L型骨牌的棋盘覆盖问题
- 【数据结构与算法】最大子序列和问题的求解
- 数据结构与算法中的“递归”——用回溯法求解8皇后问题
- 《数据结构与算法分析》贪婪算法与分治算法--二维最近点问题详解
- 分治法求解逆序数问题
- 分治法求解最大子数组问题
- 最近对问题,分治法求解
- 分治法求解最大子数组问题
- 众数问题(分治法求解-mtzhang)
- 分治法求解最近点对问题
- 分治算法--汉诺塔问题
- 最大子序列求解及分治算法的一些例子
- LoRa学习:LoRa数据接受发送流程(FIFO)
- OkHttp解析数据,RecyclerView和Glide的加载图片
- 側拉加fragment联动
- 免费的图书管图书借阅管理系统
- Linux安装Nginx报错make: *** No targets specified and no makefile found. Stop.解决方法
- 算法与数据结构-分治法及汉诺塔问题求解
- 第四周项目(1)-单链表的的建立
- 第四周 项目6
- String API
- 被百度的乱七八糟的新闻八卦忽悠了一早上
- 剑指offer——51.构建乘积数组
- lgov的覆盖率文件语法
- java过滤器中调用spring管理的接口
- 友盟QQ登录分享