算法分析与设计

算法分析与设计

第2章 递归与分治策略

一、为什么提出分治法

有时候要求解的问题的【问题规模】太大了,直接解决过于困难

那不如我们把它分为许多个【子问题】,这些【子问题】与原问题很相似

【子问题】与【原问题】具有相同的性质

即 【原问题的解】 = 子问题1 + 子问题2 + 子问题3 + 。。。。。。

在【分治法】中常用的解决问题的技术是【递归技术】

二、递归是什么?

2.1 递归的概念

在【定义自身】的同时,又【直接】\【间接】的调用自己

2.2 递归的特点
  • 描述简洁
  • 结构清晰简单
  • 容易证明算法的正确性
2.3 递归中应该注意什么问题呢?
  • 要有中止条件

    递归的算法会出现自身调用自身的情况,如果没有终止条件,那就会一直调用自身,无法停止

  • 所谓的“简单问题”或者“小问题” 是指离中止条件更近的问题,且其解法与“大问题”相同。

2.4 如果编写递归算法呢?

举个例子:求:f(n) = n!

  • 首先告知编写递归函数的步骤【递推】【回归】,接下来让我们感性的认识这两个概念

  • 【递归】

    要求 n! —》

    就是求 n * (n-1) ! —》

    就是求 (n-1)! = (n-1) * (n-2)! -----》

    。。。 ----》

    就是求 2 ! = 2 * 1!

    这里 1!= 1 也就是终止条件

  • 【回归】

    已知 1! = 1

    那就知道 2 ! = 2 * 1! = 2 * 1

    那就知道 3! = 3 * 2!= 3 * 2

    .。。。。。

    就知道 (n-1) ! = (n-1) * (n-2)!

    就知道 n! = n * (n-1)!

2.5 递归的适用情况?
  • 我们已经知道了【递归是什么】,如何写【递归函数】的步骤

    但是在什么情况下才应该用【递归】呢?

    1. 问题的定义是递归的

    如斐波那契数列

    F(n) = 1 n=0, 1

    ​ F(n-1) + F(n-2) n >1

    1. 递归定义的【数据结构】

    链表、二叉树。。。

2.6 举个例子
  • 汉诺塔问题

    现在有三根柱子,标号为X,Y,Z,X柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,现 在把所有盘子一个一个移动到柱子Z上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,请问至少需要多少次移动,设移动次数为H(n)。

  • 分析

    n 【盘子数量】

    n=1 A–>C 一次

    n=2 A–>B A–>C B—>C 三次

    n=3 七次【过程略 0.0】

    n很大很大 写不出来了

    我们这时候就可以用【递归】来解决这个问题

  • 过程

    当n=1时,将 编号为1的圆盘 从X柱子直接移到柱子Z上。

    当n>1时,需要利用柱子Y作为辅助柱子,设法将n-1个较小的盘子按规则移到柱子Y中,然后将编号为n的盘子从X柱子移到Z柱子,最后将n-1个较小的盘子移到Z柱子中。

    	void  Hanoi(int n,int X,int Y,int Z){//通过Y,把n个盘子从 X-->Z
            //MOVE(n,a,b) 移动n 从a --》 b
    	       if(n==1)  MOVE(1,X,Z)
    	       else 
               {
                   Hanoi(n-1,X,Z,Y);
                   MOVE(1,X,Z);
                   Hanoi(n-1,Y,X,Z);
    	 		 
    	       }
    	}
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值