1.递归与分治

一、递归与分治概述:

1.分治法的设计思想

  • 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之

分治法的可行性(前提条件):

  • ①如果原问题可以分成k个子问题,1<k<=n
  • ② 子问题都可解
  • ③ 可利用子问题的解求出原问题的解
  • 问题分解是求解复杂问题时很自然的做法。
  • 求解一个复杂问题可以将其分解成若干个子问题,子问题还可以进一步分解成更小的问题,直到分解所得的小问题是一些基本问题,并且其求解方法是已知的,可以直接求解为止。
  • 将要求解的较大规模的问题分割成k个更小规模的子问题。
  • 对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
  • 将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。

通常,由分治法所得到的子问题与原问题具有相同的类型。如果得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出不用进一步细分就可求解的子问题。由此可知,分治法求解很自然地可用一个递归过程来表示。

总而言之:分治法作为一种算法设计策略,要求分解所得的子问题是同类问题,并要求原问题的解可以通过组合子问题的解来获取

2、递归的概念

定义:
 直接或间接地调用自身的算法称为递归算法
 用函数自身给出定义的函数称为递归函数

由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便:
 在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子
问题缩小到很容易直接求出其解。
 这自然导致递归过程的产生。

分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

  • 递归的使用场合
    ① 数据结构本身是递归定义的,其实现算法往往是递归算法,比如二叉树和图等
    ② 求解过程需要递归,算法描述简捷其易于理解及分析,比如阶乘计算

使用例子

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//1.阶乘
int factorial(int n)
{
    
    
	if (n==0) 
        return 1;
	return n*factorial(n-1);
}

//2.第n个Fibonacci数可递归地计算如下
int fibonacci(int n)
{
    
    
	if (n <= 1) 
		return 1;
	return fibonacci(n-1)+fibonacci(n-2);
}

//3.Ackerman函数
public class Ackerman {
    
    
    public static void main(String[] args) {
    
    
        // TODO 自动生成的方法存根
        Scanner scan = new Scanner(System.in);  
        int n = scan.nextInt();
        int m = scan.nextInt();
        System.out.println(Ackerman1(n, m));
    }
    public static int Ackerman1(int n,int m){
    
       
        if(n==0 && m>=0)return 1;
        if(n==1 && m==0)return 2;
        if(n>=2 && m==0)return n+2;
        if(n>=1 && m>=1) 
            return Ackerman1(Ackerman1(n-1,m),m-1);
        return -1;
    }
}
//4 排列问题

猜你喜欢

转载自blog.csdn.net/weixin_44953928/article/details/124787257