递归与分治算法解析

递归与分治算法解析

递归

递归的概念:直接或者间接调用自身算法称为递归算法,像俄罗斯套娃一样一层一层
在这里插入图片描述

分治

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

分治法使用的场景

  1. 该问题的规模缩小到一定程度就可以容易的解决;

  2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;

  3. 利用该问题分解出子问题的解,可以合并为该问题的解;

  4. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题;

分治与递归像是一堆孪生兄弟,经常同时应用在算法设计中

在这里插入图片描述

递归

下面用一个简单的斐波那契数列(Fibonacci)来为大家演示一下递归算法

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)

在这里插入图片描述
C++实现

#include<bits/stdc++.h>
using namespace std;
//递归调用fibonacci函数 
int fibonacci(int n){
    
    
	//如果小于1则结束递归直接返回 
 if(n<=1){
    
    
 	return 1;
 } 
 return fibonacci(n-1)+fibonacci(n-2); 
} 

int main(){
    
    
	int n;
	int sum;
	while(cin>>n&&n!=-1){
    
    
		sum=fibonacci(n);
	    cout<<"值:"<<sum<<endl; 
	}
} 

在这里插入图片描述
java实现

package 递归与分治;
import java.util.Scanner;
public class Fibonacci2 {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int sum=fibonacci(n);
        System.out.println("值:"+sum);
    }
    static int fibonacci(int a){
    
    
        if(a<=1){
    
    
            return 1;
        }
        return  fibonacci(a-1)+fibonacci(a-2);
    }
}

在这里插入图片描述

正整数n的划分

题目描述:

有一个正整数 n,如果存在 n1 + n2 + … + nk = n (nk > 0),则称 {n1, n2, …, nk} 为正整数 n 的一个划分
问正整数 n 一共有多少个划分?

解题思路

(1) 当 n == 1 或者 m == 1 的时候,f(n, m) = 1
(2) 当 n == m 时,f(n, m) = f(n, m - 1) + 1
因为在 n 的所有划分中,最大加数为 n 时,只有一种划分,即 {n}
所以,f(n, m) 就等于最大加数为 m - 1 的划分数加 1
(3) 当 n < m 时,f(n, m) = f(n, n)
因为在 n 的所有划分中,最大加数只能小于等于 n
(4) 当 n > m 时,f(n, m) = f(n, m - 1) + f(n - m, m)
f(n, m - 1) 为最大加数小于等于 m - 1 的划分数
当最大加数为 m 时,那么每个划分序列有了一个 m,还差 n - m
就相当于是 n - m 有多少个最大加数小于等于 m 的划分数,即 f(n - m, m)
这两部分之和就等于 f(n, m)

c++实现

#include<bits/stdc++.h>
using namespace std;
int IntegerDivsion(int n,int m){
    
    
	if(n==1||m==1){
    
    
		return 1;
	}
	 if(n<1||m<1){
    
    
		return 0;
	}
    if(n<m){
    
    
		return IntegerDivsion(n,n);
	}
	if(n==m){
    
    
		return IntegerDivsion(n,m-1)+1;
	}
	 if(n>m){
    
    
		return IntegerDivsion(n,m-1)+IntegerDivsion(n-m,m);
	}
}



int main(){
    
    
	//要拆解的整数 
    int n;
    //最大加数
	int m; 
	cin>>n;
	cin>>m; 
	//结果
	int sum; 
	sum=IntegerDivsion(n,m);
	cout<<sum; 
} 


分治

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且原生问题相同,递归的解决这些子问题,
然后将各个子问题的解合并并得到原问题的解

最常见的分治是二分,而且是均分。理论研究指出,各个子问题的规模均衡时,算法效率最高。分治法的实现算法往往是递归算法。
下面来实现一下二分查找

题目链接:https://leetcode-cn.com/problems/binary-search/

#include<iostream>
using namespace std;
int search(int* nums, int numsSize, int target){
    
    
	//left=0开始 
	int left=0;
	//right从最高处开始 
	int right=numsSize-1;
	while(left<=right){
    
    
		int middle=(right+left)/2;
		if(target==nums[middle]){
    
    
			return middle;
		}
		else if(target>nums[middle]){
    
    
	      left=middle+1; 
	}
	else{
    
    
	   right=middle-1 ;
	} 
	
}
   return -1;
}

int  main(){
    
    
  int a[6]={
    
    -1,0,3,5,9,12};
  int target ;
  cin>>target; 
  int result=search(a,6,target);
  cout<<"下标:"<<result<<endl;	
	return 0;
} 

以上就是递归与分治算法解析的内容,如有帮助还请点赞关注支持,如有疑问评论私信都可,看到后可帮助解答本博客主要侧重于数据结构于算法和java开发,操作系统,计算机网络,觉得我的文章有帮助的小伙伴可以关注我,有疑问可评论私信,相逢即是缘,大家高处见

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/pjh88/article/details/109141155