分治算法入门

分治算法

韩顺平数据结构算法与笔记

介绍

一个复杂的问题分解成两个或者多个相同或相似的小问题,再把小问题划分成更小的问题

分治算法可以求解的一些经典问题
二分搜索
大整数乘法
棋盘覆盖
合并排序
快速排序
线性时间选择
最接近点对问题
循环赛日程表
汉诺塔

难点:怎么把大问题划分成小问题

基本步骤

1)分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题

2)解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

3)合并:将各个子问题的解合并为原问题的解。

设计模式

if |P|< nO		p代表问题的规模
	then return(ADHOC(P))
//将P分解为较小的子问题P1 ,P2..
for i <-1 to k
do yi <- Divide-and-Conquer(Pi)递归解决Pi |
T <- MEREGE(12_,.yk)合并子问题
return(T)

其中|P|表示问题P的规模; n0为一阈值,表示当问题P的规模不超过n0时,. 问题己容
易直接解出,不必再继续分解。ADHOC§是该分治法中的基本子算法,用于直接解
小规模的问题P。~因此,当P的规模不超过n0时直接用算法ADHOC§求解。算法
MERE(y/,2y2.yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 …k的相应
的解y.,2…yk合并为P的解。

应用案例——汉诺塔

思路

我们从只有一个盘开始推导

发现一个规律,我们可以把所有的盘看成只有两个盘,最下面的盘和上面所有的盘

而且,总是把最下边的盘移动到第三个柱子上,然后把剩下上面的盘移动到第三个盘上就行了

package 算法;
//汉诺塔---------分治算法
public class DAC {
	public static void main(String[] args) {
		hanoiTower(6, 'A', 'B', 'C');
	}

	/**
	//汉诺塔的移动方案 -- 分治算法
	 * @param num		盘子数目
	 * @param a			第一个柱子
	 * @param b			第二个柱子
	 * @param c			第三个柱子
	 */
	public static void hanoiTower(int num,char a,char b,char c){
		//如果只有一个盘
		if(num == 1){
			System.out.println("第一个盘从"+a+"->"+c);
		}else{
			//如果是 num>=2的情况,我们总是可以看做两个盘,最下面的盘和上面所有盘
			//1.先把最上面的所有盘A->B
			hanoiTower(num-1, a, c, b);
			//2.把最下面的盘从A移动到C
			System.out.println("第"+num+"个盘从"+a+"->"+c);
			//3.把B塔所有盘--->C			移动过程使用到A塔
			hanoiTower(num-1, b, a, c);
		}
	}
}

这个地方一定不能迷,我们在递归的时候,从那个柱子移动到那个柱子就是递归的时候前后位置一定要注意,a->c那就是abc a->b那就是acb,我们不能纠结这样写为啥就移上去了,自己知道流程就好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会写代码的花城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值