算法设计-最全详细知识总结-递推+递归法+分治法+动态规划+贪心算法+回溯算法+分支法(Java版)

本文详细总结了算法设计中的重要概念,涵盖递推、递归、分治、动态规划、贪心算法、回溯法和分支法。通过实例讲解了欧几里德算法、阶乘、Fibonacci数列、汉诺塔问题、二分搜索、快速排序、背包问题和最短路径问题。同时,深入探讨了每种算法的思想、应用场景和代码实现,旨在帮助读者深入理解并掌握这些经典算法。
摘要由CSDN通过智能技术生成

传统算法-知识总结-递推+递归+分治+动态规划+贪心算法+回溯算法+分支

目录

一:算法基础

1.1.算法基础介绍

1.1.1 算法满足4条性质:

1.1.2 算法定义:

1.1.3 算法设计过程

1.2.欧几里德算法介绍

1.2.1 定义:

1.2.2 算法内容:

1.2.3 算法证明:

二.递推

2.1 递推的定义

2.2 迭代法求解递推方程

2.3 递推样例

2.3.1 一元多项式求导

2.3.2分鱼程序

三:递归

3.1 递归:

3.2 实例:

3.2.1 阶乘

3.2.2 Fibonacci数列:

3.3 经典hanoi塔问题

3.3.1 问题定义:

3.3.2 解题思路

3.3.3Java代码实现hanoi塔

四:分治

4.1 分治的基本概念

4.1.1.基本介绍

4.1.2 算法的一般设计模式

4.2 二分搜索技术

4.2.1 Java中封装的二分搜索

4.2.2二分搜索描述和思想

4.2.3 代码实现:

4.3 快速排序

4.3.1 快排的定义和思想:

4.3.2 图解快排过程

4.3.3 代码实现

五:贪心算法

5.1 贪心算法基本概念

5.1.1 定义

5.1.2 贪心算法的基本思路

5.1.3 贪心算法适用问题

5.2 背包问题

六:动态规划

6.1 动态规划引例-钞票使用问题

6.1.1 问题描述

6.1.2 如何避免不是最优解

6.1.3 钞票问题代码

6.2 基本概念:

6.2.1 动态规划的定义:

6.2.2 无后效性

6.2.3 最优子结构

6.3 动态规划样例:最长公共子系列

6.3.1 最长子问题描述:

6.3.2 最长子问题分析

6.3.3 最长子问题解决

七:回溯法

7.1 回溯法的基本定义和思想

7.2 回溯法的解题步骤

7.3 回溯法代码框架

7.3.1 递归回溯框架

7.3.2 非递归的算法框架

7.4 n皇后问题

7.4.1 题目描述

74.2.代码实现

八:分支限界

8.1.基本介绍

8.2 分支限界法与回溯法的区别

8.3 分支限界--单源最短路径问题

8.3.1 单源最短路径问题介绍

8.3.2 单源最短路径问题思路

8.3.3 单源最短路径问题代码实现

九.参考文献


一:算法基础

1.1.算法基础介绍

1.1.1 算法满足4条性质:

1)输入:有0个或者多个由外部提供的的量作为算法的输入

2)输出:算法产生至少一个量作为输出

3)确定性:组成算法的每条指令是清晰的和无歧义的

4)有限性:算法中每条指令的执行次数是有限的,执行每条指令的时间也是有限的。

1.1.2 算法定义:

1.1.3 算法设计过程

1.2.欧几里德算法介绍

1.2.1 定义:

        欧几里德算法也被称为辗转相除法,用于计算两个整数a, b的最大公因子。符号记为:gcd(a,b).特别gcd(0, n) = 0,因为任何整数都能整除0;

1.2.2 算法内容:

通俗的讲:假设a比b大,我们要找a, b的最大公因子。第一步,用a除以b余数为y.第二步:把第一步中的除数当作被除数,把第一步中的余数当作除数再进行相除;第三步:重复第二步的步骤,一直到余数为0,结束算法,此时剩余的最后的被除数就是我们要找的最大公因子。

1.2.3 算法证明:

        对于任何可以整除a和b的整数,那么它也一定可以整除(a-b)和 b.选择该整数为gcd(a, b);同理,任何可以整除a-b和b的整数,一定可以整除a和b,因此我们选择该整数为gcd(a-b,b);由此可得:gcd(a,b)=gcd(a-b,b)。

     因为总有整数n,使得 a - n*b = a mod b,所以迭代可知:gcd(a-b,b)=gcd(a-2b,b)=...=gcd(a-n*b,b)=gcd(a mod b,b)。

二.递推

2.1 递推的定义

一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系,在计算时,如果可以找到前后过程之间的数量关系(即递推式),那么,从问题出发逐步推到已知条件,此种方法叫逆推。无论顺推还是逆推,其关键是要找到递推式。

递推算法的首要问题是得到相邻的数据项间的关系(即递推关系)。递推算法避开了求通项公式的麻烦,把一个复杂的问题的求解,分解成了连续的若干步简单运算。一般说来,可以将递推算法看成是一种特殊的迭代算法

2.2 迭代法求解递推方程

不断用递推方程的右部替换左部,每次替换,随着 n 的降低在和式中多出一项,直到出现初值停止迭代,将初值代入并对和式求和
可用数学归纳法验证解的正确性

2.3 递推样例

2.3.1 一元多项式求导

(1)题目

(2)c语言求解

(3)Java语言求解

注意四个细节

  • 第一个坑:数字之间可能有多个空格 如果你是用Java切割字符串的话
  • 第二个坑:当系数项是0的时候输出0 0  *如:3  4  -5  2  6  1  0  1  对应输出是12  3  -10  1  6  0  0 但是题目给出的输出是 12  3  -10  1  6  0
  • 第三个坑:当系数项不是0,指数是0的时候   什么也不输出    *如:3  4  -5  2  6  1  -2  0  对应输出是12  3  -10  1  6  0  (-2  0没对应的数字输出)
  • 第四个坑:当输出多项式是空串的时候要输出0 0  *如:输入只有 -2  0  的时候   输出空串  但是此时必须输出0  0

代码实现:

package temp;

import java.util.ArrayList;
import java.util.Scanner;
public class algorithmtest001 {
	public static void main(String arg[]) {
		System.out.println("请输入整数: ");
		
		int n,fac;
		Scanner scan = new Scanner(System.in);
		String str = scan.nextLine();
		String[] newstr =str.split("\\s+");
		ArrayList<Integer>alist = new ArrayList<Integer>();
		for(int i=0;i<newstr.length;i=i+2) {
			int j = i+1;
			if(Integer.valueOf(newstr[i])==0){
				alist.add(0);
				alist.add(0);
			}
			if(Integer.valueOf(newstr[i])!=0&&Integer.valueOf(newstr[j])==0) {
				
			}
			if(Integer.valueOf(newstr[i])!=0&&Integer.valueOf(newstr[j])!=0) {
				alist.add(Integer.valueOf(newstr[i])* Integer.valueOf(newstr[j]));
				alist.add(Integer.valueOf(newstr[j])-1);
			}
		}
		
	    if(alist.isEmpty()){            //如果将要输出的是空字符串,那么就输出0 0  
	        System.out.println("0 0"); 
        }else{ 
        	for(int i=0 ;i<alist.size() ;i++){ 
			    System.out.print(alist.get(i)); 
	                if(i!=alist.size()-1){   
	                	System.out.print(" ");  //行末不能有空格  控制空格的输出 
	                }
			    } 
            }
	    System.out.println(); 
	}
	
}

2.3.2分鱼程序

题目:

        A、B、C、D、E五个人在某天夜里合伙去捕鱼,到第二天凌晨时都疲惫不堪,于是各自找地方睡觉。日上三杆,A第一个醒来,他将鱼分为五份,把多余的一条鱼扔掉,拿走自己的一份。B第二个醒来,也将鱼分为五份,把多余的一条鱼扔掉,保持走自己的一份。C、D、E依次醒来,也按同样的方法拿走鱼。问他们合伙至少捕了多少条鱼?

这个程序非常巧妙,先给a[0]一个初值为6,然后利用6去计算其他的鱼,在进行判断比较。


package temp;

import java.util.ArrayList;
import java.util.Scanner;
public class algorithmtest001 {
	public static void main(String arg[]) {
		int countsum = 6;
		for(int i=6; ;i++)
		{
			int count2 =(i-1)/5*4;
			int count3 = (count2-1)/5*4;
			int count4 = (count3-1)/5*4;
			int count5 = (count4-1)/5*4;
			if(i%5==1&&count2%5==1&&count3%5==1&&count4%5==1&&count5%5==1) {
				System.out.println(i);
				break;
			}
		}
	}
	
}

三:递归

3.1 递归:

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

3.2 实例:

3.2.1 阶乘

(1)阶乘函数可递归定义为:

(2)代码实现

import java.util.Scanner;
public class algorithmtest001 {
	public static void main(String arg[]) {
		System.out.println("请输入整数: ");
		int n,fac;
		Scanner scan = new Scanner(System.in);
		n= scan.nextInt();
		//int []Result_Seq=new int[n];
		fac = factorial(n);
		System.out.println(fac);
	}
	
	public static int factorial(int m) {
		if(m==0) return 1;
		else return m*factorial(m-1);
	}
}

3.2.2 Fibonacci数列:

 (1)定义:

        无穷数列1,1,2,3,5,8,13,21,34,55,........,称为Fibonacci数列,表现形式:

(2)代码实现

import java.util.Scanner;
public class algorithmtest001 {
	public static void main(String arg[]) {
		System.out.println("请输入整数: ");
		int n,fac;
		Scanner scan = new Scanner(System.in);
		n= scan.nextInt();
		//int []Result_Seq=new int[n];
		fac = fibonacci(n);
		System.out.println(fac);
	}
	
	public static int fibonacci(int m) {
		if(m<=1) return 1;
		else return fibonacci(m-1)+fibonacci(m-2);
	}
}

3.3 经典hanoi塔问题

3.3.1 问题定义:

    汉诺塔是根据一个传说形成的一个问题。汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。


我们将 Hanoi 问题抽象为一种数学问题。首先给出如下三个柱子 A、B、C,其中 A 柱子上有从上到下从小叠到大的 N 个云盘。现要求将A柱子上的圆盘都移动到 C 柱子上,其中,每次移动都必须满足:

每次只能移动一个圆盘
小圆盘上不能放大圆盘
那么针对这个数学问题,就可以提出相关问题:

移动 N 个圆盘最少需要多少次
第 M 步移动的是哪个圆盘以及圆盘移动方向
解题:设总共有 N 个圆盘,Steps表示总移动次数

3.3.2 解题思路

3.3.3Java代码实现hanoi塔

import java.util.ArrayList;
import java.util.Scanner;
public class algorithmtest001 {
	static long s = 0;
	 
	public static void main(String args[]) {
		System.out.println("开始hanoi塔游戏 ");
		int n = 0;
		Scanner console = new Scanner(System.in);
		n = console.nextInt();
		System.out.print
  • 9
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值