loop、iterate、traversal和recursion这几个词

2024-03-29 07:48

本文主要是介绍loop、iterate、traversal和recursion这几个词,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

loop、iterate、traversal和recursion这几个词

先摘抄“为之漫笔”对这几个概念的一段理解:

loop、iterate、traversal和recursion这几个词是计算机技术书中经常会出现的几个词汇。众所周知,这几个词分别翻译为:循环、迭代、遍历和递归。乍一看,这几个词好像都与重复(repeat)有关,但有的又好像不完全是重复的意思。那么这几个词到底各是什么含义,有什么区别和联系呢?下面就试着解释一下。

  • 循环(loop)
    指的是在满足条件的情况下,重复执行同一段代码。比如,while语句。
  • 迭代(iterate)
    指的是按照某种顺序逐个访问列表中的每一项。比如,for语句。
  • 遍历(traversal)
    指的是按照一定的规则访问树形结构中的每个节点,而且每个节点都只访问一次。
  • 递归(recursion)
    指的是一个函数不断调用自身的行为。比如,以编程方式输出著名的斐波纳契数列。

有了以上定义,这几个概念之间的区别其实就比较清楚了。至于它们之间的联系,严格来讲,它们似乎都属于算法的范畴。换句话说,它们只不过是解决问题的不同手段和方式,而本质上则都是计算机编程中达成特定目标的途径。

迭代
迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。

利用迭代算法解决问题,需要做好以下三个方面的工作:

确定迭代变量。在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。
建立迭代关系式。所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。
对迭代过程进行控制。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件。
可以用迭代的算法有很经典的问题,比如兔子产子问题:假定你有一雄一雌一对刚出生的兔子,它们在长到一个月大小时开始交配,在第二月结束时,雌兔子产下另一对兔子,过了一个月后它们也开始繁殖,如此这般持续下去。每只雌兔在开始繁殖时每月都产下一对兔子,假定没有兔子死亡,在一年后总共会有多少对兔子?

还有上楼梯的走法问题:有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法?

这两个问题可以参看以前写的一篇文章:趣味算法之兔子产子问题

迭代与循环
先从字面上看:

迭代:“迭”:轮流,轮番,替换,交替,更换。“代”:代替。所以迭代的意思是:变化的循环,这种变化就是轮番代替,轮流代替。
循环:不变的重复。
个人认为迭代是循环的一种,循环体代码分为固定循环体,和变化的循环体。

固定的循环举例:

for($i=0; $i < 8; $i++){echo 'Welcome to NowaMagic';
}

上面的迭代是常见的递增式迭代。类似的还有递减式迭代,递乘式迭代。

$sum = 0;for($i = 1; $i <= 1000; $i++ ){$sum = $sum + i;
}

迭代的好处:迭代减少了冗余代码,提高了代码的利用率和动态性。

循环、迭代与递归

  1. 递归算法与迭代算法的设计思路区别在于:函数或算法是否具备收敛性,当且仅当一个算法存在预期的收敛效果时,采用递归算法才是可行的,否则,就不能使用递归算法。
    当然,从理论上说,所有的递归函数都可以转换为迭代函数,反之亦然,然而代价通常都是比较高的。但从算法结构来说,递归声明的结构并不总能够转换为迭代结构,原因在于结构的引申本身属于递归的概念,用迭代的方法在设计初期根本无法实现,这就像动多态的东西并不总是可以用静多态的方法实现一样。这也是为什么在结构设计时,通常采用递归的方式而不是采用迭代的方式的原因,一个极典型的例子类似于链表,使用递归定义及其简单,但对于内存定义(数组方式)其定义及调用处理说明就变得很晦涩,尤其是在遇到环链、图、网格等问题时,使用迭代方式从描述到实现上都变得很不现实。

  2. 递归其实是方便了程序员难为了机器。它只要得到数学公式就能很方便的写出程序。优点就是易理解,容易编程。但递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,对嵌套层数深的一些算法,递归会力不从心,空间上会以内存崩溃而告终,而且递归也带来了大量的函数调用,这也有许多额外的时间开销。所以在深度大时,它的时空性就不好了。
    循环其缺点就是不容易理解,编写复杂问题时困难。优点是效率高。运行时间只因循环次数增加而增加,没什么额外开销。空间上没有什么增加。

  3. 局部变量占用的内存是一次性的,也就是O(1)的空间复杂度,而对于递归(不考虑尾递归优化的情况),每次函数调用都要压栈,那么空间复杂度是O(n),和递归次数呈线性关系。

  4. 递归程序改用循环实现的话,一般都是要自己维护一个栈的,以便状态的回溯。如果某个递归程序改用循环的时候根本就不需要维护栈,那其实这个递归程序这样写只是意义明显一些,不一定要写成递归形式。但很多递归程序就是为了利用函数自身在系统栈上的auto变量记录状态,以便回溯。

原理上讲,所有递归都是可以消除的,代价就是可能自己要维护一个栈。而且我个人认为,很多情况下用递归还是必要的,它往往能把复杂问题分解成更为简单的步骤,而且很能反映问题的本质。

递归其实就是利用系统堆栈,实现函数自身调用,或者是相互调用的过程。在通往边界的过程中,都会把单步地址保存下来,知道等出边界,再按照先进后出的进行运算,这正如我们装木桶一样,每一次都只能把东西方在最上面,而取得时候,先放进取的反而最后取出。递归的数据传送也类似。但是递归不能无限的进行下去,必须在一定条件下停止自身调用,因此它的边界值应是明确的。就向我们装木桶一样,我们不能总是无限制的往里装,必须在一定的时候把东西取出来。比较简单的递归过程是阶乘函数,你可以去看一下。但是递归的运算方法,往往决定了它的效率很低,因为数据要不断的进栈出栈。

但是递归作为比较基础的算法,它的作用不能忽视。

转载来源

http://www.nowamagic.net/librarys/veda/detail/2324

这篇关于loop、iterate、traversal和recursion这几个词的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/858026

相关文章

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

Verybot的几个视频

1、Verybot的运动控制                 http://v.youku.com/v_show/id_XNjYxNjg4MTM2.html           2、Verybot比较初步的网络视频监控           http://v.youku.com/v_show/id_XNjYxNjkyMjg0.html           3、V

PHP原理之内存管理中难懂的几个点

PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等. 另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们

Java虚拟机垃圾回收的几个关键问题

20151008 GC的几个关键问题,触发条件,触发的机制 主线是数据的移动,从什么位置到什么位置,移动的条件是什么? 1 垃圾收集在什么时候触发? GC都是在带满了的时候触发的,每次触发都是把不会用的不可达的对象空间回收了,留下还在用的对象。 1) MinorGC的触发是伊甸园空间满的时候 2) FullGC的触发是在老年代满的时候 2 垃圾回收的时候做哪些工作? 1) 一个新的对象new出

myEclipse失去焦点时报错Unhandled event loop exception的解决方案

一句话:百度杀毒惹的祸。。。。果断卸载后问题解决。

多表连接的三种方式hash join,merge join,nested loop

多表之间的连接有三种方式:Nested Loops,Hash Join和 Sort Merge Join. 下面来介绍三种不同连接的不同:     一. NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大(大于1 万不适合),要把返回

vivado error:Combinatorial Loop Alert:1 LUT cells form a combinatorial loop

VIVADO ERROR :Combinatorial Loop Alert:1 LUT cells form a combinatorial loop vivao生成bit流时发生报错,如下图所示定位原因解决 vivao生成bit流时发生报错,如下图所示 定位原因 在三段式状态机中,组合逻辑代码if else 语句未写全只写了if…elsif…,没有写else,导致错误

全网第一份 | Flink学习面试灵魂40问,看看你能答上来几个?

《2021年最新版大数据面试题全面开启更新》 答案将在下期给出。   概念和基础篇   简单介绍一下Flink Flink相比传统的Spark Streaming有什么区别?和Spark中的structured streaming 相比呢?Flink相比ss和storm有什么优势? Flink的组件栈是怎么样的? Flink的基础编程模型了解吗?