`
凌霄剑影
  • 浏览: 7929 次
  • 性别: Icon_minigender_1
  • 来自: 浙江
最近访客 更多访客>>
社区版块
存档分类
最新评论

递归 or 循环?!

阅读更多

递归 or 循环?!

 

      递归和循环是两个相似的方法,在初次使用中,常常不容易分辨清楚,导致很多人不敢轻易使用。关于我对这两个东东的一点点总结,如下:

 

一. 递归

 

百度上的定义:

  程序调用自身的编程技巧称为递归(recursion)。

  一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

  注意:

  (1) 递归就是在过程或函数里调用自身;

   *(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

 

用于解决三类问题:

  (1)数据的定义是按递归定义的。(Fibonacci函数)(例2)

  (2)问题解法按递归算法实现。(回溯) (例3)

  (3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)

 

递归的优缺点:

        优点:代码简洁、清晰,并且容易验证正确性。(如果你真的理解了算法的话,否则你更晕) 

        缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。 

 

个人观点

        递归的运用主要是把大而且重复的操作用不断调用自己的方法来实现减少代码量的目的。虽然代码减少,但是可读性也随之降低。递归中,最重要的就是递归的退出条件没有退出条件的递归就是死递归。掌握好每个递归的退出条件,才能更好的使用递归。

 

二. 循环

 

百度上的定义:

        一组被重复执行的语句称之为循环体,能否继续重复,决定循环的终止条件。循环语句是由循环体循环的终止条件两部分组成的。

        要使用循环语句时,必须要确定循环体及条件(布尔表达式)两个重要因素,亦即首要考虑的是:我要重复执行哪些语句我要重复到什么时候为止

 

循环的优缺点:

        优点:速度快,结构简单。
        缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。
 

与递归的比较:

        他们的不同点在于:递归是调用自己本身,而循环是不断执行循环体。递归效率低。

        他们的共同点在于:都有结束条件,化繁为简。

      *如例1中,其中num在递归中只能到6000左右就会报栈溢出的错误,而在循环中却没有限制。

 

 

三. 实例

1. 叠加

import java.awt.Graphics;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JFrame;

public class compare{
	public static long summey;

	/**
	 * 递归和循环的对比
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// 开始
		Calendar calendar = new GregorianCalendar();
		long start = calendar.getTimeInMillis();
		// 实验体
		recursion(6000);
		// 结束
		Calendar calendar1 = new GregorianCalendar();
		long end = calendar1.getTimeInMillis();
		long b = end - start;
		System.out.println("运行时间: " + b);
	}

	/**
	 * 循环
	 * 
	 * @param num:传入的数
	 * @return:总数
	 */
	public static long circle(long num) {
		long sum = 1;
		for (long i = 1; i <= num; i++) {
			sum = sum + i;
		}
		return sum;
	}

	/**
	 * 递归
	 * 
	 * @param num:传入的数
	 * @return:总数
	 */
	public static long recursion(long num) {
		if (num == 1)
			return 1;
		else {
			summey = num + recursion(num - 1);
		}
		return summey;
	}
}

 

  2. Fibonacci函数

public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
}

 

   3. Hanoi问题

package Hanoi;

import java.io.*;

public class Hanoi {
	/**
	 * 主类
	 * 
	 * @param args
	 * @throws IOException
	 */
	public static void main(String args[]) throws IOException {
		Hanoi ha = new Hanoi();
		ha.go();
	}
	/**
	 * 运行的方法
	 * 
	 * @throws IOException
	 */
	public void go() throws IOException {
		int n;
		// 创建一个输入流,将接收到的数字作为要用的数
		BufferedReader buf;
		buf = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("请输入盘数:");
		n = Integer.parseInt(buf.readLine());
		Hanoi hanoi = new Hanoi();
		hanoi.move(n, 'A', 'B', 'C');
	}
	/**
	 * 移动
	 * @param n:总个数
	 * @param a:形参指A盘
	 * @param b:形参指B盘
	 * @param c:形参指C盘
	 */
	public void move(int n, char a, char b, char c) {
		if (n == 1) {
			System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
		} else {
			move(n - 1, a, c, b);
			System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
			move(n - 1, b, a, c);
		}
	}
}

 

 

 

分享到:
评论

相关推荐

    提升Python效率之使用循环机制代替递归函数

    当年,典型的递归题目,斐波那契数列还记得吗? def fib(n): if n==1 or n==2: return 1 else: return fib(n-1)+fib(n-2) 当然, 为了程序健壮性,加上 try...except... def fib(n): if isinstance(n, int): ...

    python基础编程:提升Python效率之使用循环机制代替递归函数

    这篇文章主要介绍了提升Python效率之使用循环机制代替递归函数的相关知识,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 斐波那契数列 当年,典型的递归题目,斐波那契数列还记得吗? ...

    详解如何在JS代码中消灭for循环

    但是我依然坚持认为 JS 引擎应该支持尾调优化,写尾递归和写循环性能没差别。 一,用好 filter,map,和其它 ES6 新增的高阶遍历函数 问题一: 将数组中的 falsy 值去除 const arrContainsEmptyVal = [3, 4, 5, 2,...

    解读JavaScript中 For, While与递归的用法

    for循环: 代码如下:for(i=start;...}递归:使用for循环做substring 代码如下:function substring(all, start, end) { for(i=start; i&lt;=end; i++) { console.log(all[i]); } substring(“eclipse”

    在Python中,不用while和for循环遍历列表的实例

    *****for和while循环底层用的是递归实现的 以上这篇在Python中,不用while和for循环遍历列表的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。 您可能感兴趣的文章:...

    关于java递归的笔试题-guide_to_algorithms:算法入门指南

    or 数组:查找、插入、循环 对象(哈希表):查找、循环、插入 语言特定的内置方法 数学:代数(例如,对数、指数、素数、幂) 如果您缺少一些最低要求,那么我建议您参加进修课程。 以下是一些易于消化的建议: ...

    Python迭代器协议及for循环工作机制详解

    一、递归与迭代 二、什么是迭代器协议 1、迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stopiteration异常,已终止迭代(只能往后走不能往前退) 2、可迭代对象:...

    PHP foreach遍历多维数组实现方式

    正常我们的foreach可以按顺序把一维数组里面每个 key =&gt; value 打印出来,但是如果是多维数组则需要循环在嵌套循环,或则递归实现,但是这些方式都不够灵活,因为在不确定该数组是几维的情况下,不可能永无止境的...

    图形学 报告+源码+注释 多种优美图案生成

    一.本程序实现了同时显示两种DDA算法和bresensham算法生成直线。 二.用中点算法、bresensham算法生成圆形。... 利用for循环控制100-999个数,每个数分解出个位,十位,百位。 五.生成的美丽的花朵。

    C 程序指导书及实践指导

    1、掌握在程序设计条件型循环结构时,如何正确地设定循环条件,以及如何控制循环的次数。 2、了解条件型循环结构的基本测试方法。 [实验内容与步骤] 1、下面是一个计算e的近似值(使误差小于给定的δ)的程序。 main...

    单链表反转python实现代码示例

    单链表的反转可以使用循环,也可以使用递归的方式 1.循环反转单链表 循环的方法中,使用pre指向前一个结点,cur指向当前结点,每次把cur-&gt;next指向pre即可。 代码: class ListNode: def __init__(self,x): self...

    Linux高级bash编程

    Hello or Good-bye 12-3. 删除当前目录下文件名中包含一些特殊字符(包括空白)的文件.. 12-4. 通过文件的 inode 号来删除文件 12-5. Logfile: 使用 xargs 来监控系统 log 12-6. 把当前目录下的文件拷贝到另一个文件...

    Advanced Bash-Scripting Guide <>

    Hello or Good-bye 12-3. 删除当前目录下文件名中包含一些特殊字符(包括空白)的文件.. 12-4. 通过文件的 inode 号来删除文件 12-5. Logfile: 使用 xargs 来监控系统 log 12-6. 把当前目录下的文件拷贝到另一个文件...

    freemarker总结

    此外,迭代集合对象时,还包含两个特殊的循环变量: item_index:当前变量的索引值 item_has_next:是否存在下一个对象 也可以使用指令跳出迭代 例子如下: ["星期一", "星期二", "星期三", "星期四", "星期五", ...

    Codeforces Round #617 (Div. 3), problem: (B) Food Buying

    可以使用迭代的方法,每次迭代需要更新已花钱总数和剩余钱款总数,最后剩余的钱小于10后跳出循环。也可以用递归的方法,每一层递归求出当前花的钱,返回这个数字与下一次递归的和。 我提交的是递归解: #include #...

    PySORN_0.1:自组织循环神经网络的用例和API

    为了易于安装,请导航到最新项目PySORN:预发行版本0.1.0 我的硕士论文SORN的实现“自组织递归神经网络:解决混沌的迫在眉睫的生物似的人工脑电路解决一般智力任务的前景”索恩水库连接强度的演变神经连接体支持的...

    详解用python计算阶乘的几种方法

    第二种:普通的循环 x = 1 y = int(input(请输入要计算的数:)) for i in range(1, y + 1): x = x * i print(x) 第三种:利用递归的方式 def func(n): if n == 0 or n == 1: return 1 else: retu

    微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决

    微信小程序上传图片的时候,如果是多图片上传,一般都是直接用一个循环进行wx.uploadFile 这个在电脑上面测试与苹果手机上面都不会有什么问题 但当用安卓测试的时候,你会发现小程序会提示一个the same task is ...

    leetcode答案-leetcode:leetcode

    这个题目的关键是无法确定之前子集求出的结果为最优,所以用递归求解的时候存在大量无法避免的重复计算,改为循环更新 91, 139 递归效率极低,今后动态规划有限考虑数组更新 120 240 神题 213 问题转换 not(A and B)...

    Shell脚本经典之Fork炸弹的分析与预防

    所谓fork炸弹是一种恶意程序,它的内部是一个不断在fork进程的无限循环,fork炸弹并不需要有特别的权限即可对系统造成破坏。fork炸弹实质是一个简单的递归程序。由于程序是递归的,如果没有任何限制,这会导致这个...

Global site tag (gtag.js) - Google Analytics