首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么递归函数中的迭代器在返回后指向开头?

递归函数中的迭代器在返回后指向开头的原因是因为递归函数的特性决定了每次递归调用都会创建一个新的函数栈帧,而函数栈帧中的局部变量和迭代器都是独立的。

当递归函数执行到迭代器的创建语句时,会在当前函数栈帧中创建一个新的迭代器对象,并将其指向迭代对象的开头位置。随后,递归函数会继续执行下一步操作,可能是递归调用或其他操作。

当递归函数的递归调用返回时,会销毁当前函数栈帧并返回到上一层函数栈帧。这意味着上一层函数栈帧中的迭代器对象仍然存在,并且保持着之前的状态,即指向迭代对象的开头位置。

这种设计是为了保持递归函数的状态独立性,使得每次递归调用都能够独立地操作迭代器对象,而不会相互干扰。同时,这也符合递归函数的逻辑,因为每次递归调用都是在处理迭代对象的一部分数据,而不是整个迭代对象。

需要注意的是,递归函数中的迭代器在返回后指向开头,并不意味着它会重新遍历整个迭代对象。如果需要重新遍历迭代对象,可以在递归函数中重新创建一个新的迭代器对象。

总结起来,递归函数中的迭代器在返回后指向开头是为了保持递归函数的状态独立性,使得每次递归调用都能够独立地操作迭代器对象。这样设计可以更好地支持递归函数对迭代对象的处理。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

学了链表牛刀小试,三种做法都吃透就算是学会了

对于这个问题,这题很好心地进阶里面给了我们提示,可以使用迭代或者递归方法。 我个人感觉这两种方法难度差不多,不过从理解难度上来说,递归方法更简单直观一些。...递归为什么递归方法稍微更直观呢?因为我们可以把递归函数本身当成是一个能够更小范围内运作黑盒,接着,我们要做就是像是套娃一样,让它能够更大范围当中实现同样功能。...比如在这题当中,我们要使用递归来实现reverseList函数。我们先假设,它能够比当前更小范围内运行。...实际上我们大可以不必如此,我们直接让递归函数返回末尾指针即可。但这样的话,我们就修改了返回类型,所以就要单独写一个递归来实现了。...既然如此,我们既可以每次插入末尾,自然也可以插入头部。如果我们每次插入元素都在头部的话,得到链表元素顺序刚好和之前相反。

23620

递归反转链表一部分

转载自labuladong算法小抄,go语言描述 反转单链表迭代实现不是一个困难事情,但是递归实现就有点难度了,如果再加一点难度,让你仅仅反转单链表一部分,你是否能够递归实现呢?...具体来说,我们 reverse 函数定义是这样: 输入一个节点 head,将「以 head 为起点」链表反转,并返回反转之后头结点。 明白了函数定义,来看这个问题。...并且根据函数定义,reverse 函数返回反转之后头结点,我们用变量 last 接收了。 现在再来看下面的代码: head.next.next = head ?...2、当链表递归反转之后,新头结点是 last,而之前 head 变成了最后一个节点,别忘了链表末尾要指向 null: head.next = nil 理解了这两点,我们就可以进一步深入了,接下来问题其实都是在这个算法上扩展...四、最后总结 递归思想相对迭代思想,稍微有点难以理解,处理技巧是:不要跳进递归,而是利用明确定义来实现算法逻辑。

84120

前端常见手写面试题

this: {name: 'poetries', age: 18}注意: bind之后不能再次修改this指向,bind多次执行,函数this还是指向第一次bind对象实现Array.isArray...实现迭代生成函数我们说迭代对象全凭迭代生成函数帮我们生成。...ES6,实现一个迭代生成函数并不是什么难事儿,因为ES6早帮我们考虑好了全套解决方案,内置了贴心 生成器 (Generator)供我们使用:// 编写一个迭代生成函数function *iteratorGenerator...下面我们要做,不仅仅是写一个迭代对象,而是用ES5去写一个能够生成迭代对象迭代生成函数(解析注释里):// 定义生成器函数,入参是任意集合function iteratorGenerator...(3)让函数 this 指向这个对象,执行构造函数代码(为这个新对象添加属性)(4)判断函数返回值类型,如果是值类型,返回创建对象。如果是引用类型,就返回这个引用类型对象。

33720

《C++ primer》--第三章

getline函数对空白字符处理:不忽略行开头空白字符,读取字符直至遇到换行符,读取终止并丢弃换行符(换行符从输入流中去掉但并不存储string对象)。...const迭代迭代常量,该迭代本身值不能修改,即该迭代定义时需要初始化,而且初始化之后,不能再指向其他元素。若需要指向固定元素迭代,则可以使用const迭代。...const迭代这种类型几乎没什么用处:一旦它被初始化,只能用它来改写其指向元素,但不能使它指向任何其他元素。...const_iterator是一种迭代类型,对这种类型迭代解引用会得到一个指向const对象引用,即通过这种迭代访问到得对象是常量。...道理很简单:因为前置操作需要做工作更少,只需加1返回加1结果即可。而后置操作符则必须先保存操作数原来值,以便返回未加1之前值作为操作结果。

59550

C语言详解(二) - 函数

使用某个函数时只需要知道它在哪个库函数,然后自己程序开始添加相应函数即可。 .h结尾文件是头文件。...void为返回类型意为函数没有返回值,可以程序末尾写上return;,或者不写return;,对这个函数无影响。 void*为返回值意为,函数返回一个不指向任何类型为"空"指针。...解决方法是main函数之前进行相应函数声明。 函数声明一般放在程序main函数之前,放在程序开头部分,与函数定义不同,只需要由函数头和结尾分号组成。...函数声明时函数返回类型、函数名、函数形参数据类型是必需,而形参变量名是可有可无。...{ return 0; } } 运行结果: 6.4 递归迭代 6.4.1 解释 循环是迭代一种,但迭代不一定是循环 一些问题既可以用递归实现,也可以用循环实现。

81510

前端面试遇到了这些手写题

ES6,实现一个迭代生成函数并不是什么难事儿,因为ES6早帮我们考虑好了全套解决方案,内置了贴心 生成器 (Generator)供我们使用:// 编写一个迭代生成函数function *iteratorGenerator...下面我们要做,不仅仅是写一个迭代对象,而是用ES5去写一个能够生成迭代对象迭代生成函数(解析注释里):// 定义生成器函数,入参是任意集合function iteratorGenerator...运行一下我们自定义迭代,结果符合预期:图片实现Ajax步骤创建 XMLHttpRequest 实例发出 HTTP 请求服务返回 XML 格式字符串JS 解析 XML,并更新局部页面不过随着历史进程推进...:使用定时节流函数第一次触发时不会执行,而是 delay 秒之后才执行,当最后一次停止触发,还会再执行一次函数function throttle(func, delay){ var timer...原理是维护一个计时,规定在delay时间触发函数,但是delay时间内再次触发的话,就会取消之前计时而重新设置。这样一来,只有最后一次操作能被触发。函数节流 :使得一定时间内只触发一次函数

35520

链表排序总结(全)(C++)

借助外部空间 既然数组排序简单,那可以借助数组进行排序: 把链表值一次遍历导入数组(时间复杂度O(n)) 对数组进行排序(可以选择各种算法,假设选择快排,时间复杂度O(nlogn)) 把排序元素依次放入链表节点内...数组merge函数我们已经很熟悉了: 需要一个辅助数组,大小与A[p…r]相同,双指针i,j分别指向两个待合并数组开头,假设为A[p…q],A[q+1,r]: 比较A[i]与A[j],将较小者放入辅助数组并移动指针指向下一个元素...那不符合要求并不代表归并排序不行,因为递归只是算法特定实现方式而已,我们也可以使用迭代来实现链表归并排序。...++q; } // 处理完之后beg指向是两块(已经排序好)元素最大那个节点...首先想想我们为什么不用双指针法,因为双指针需要从往前遍历啊,而单链表是没法从往前遍历

64610

链表反转(递归和非递归方式)正确姿势

; 而递归恰恰相反,首先一直迭代到链尾也就是递归基判断准则,然后再逐层返回处理到开头。...总结来说,链表翻转操作顺序对于迭代来说是从链头往链尾,而对于递归是从链尾往链头。 下面我会用详细图文来剖析其中实现细节。...1、非递归迭代)方式 迭代方式是从链头开始处理,如下图给定一个存放5个数链表。...最后一步: 2、递归方式 我们再来看看递归实现链表翻转实现,前面非递归方式是从前面数1开始往后依次处理,而递归方式则恰恰相反,它先循环找到最后面指向数5,然后从5开始处理依次翻转整个链表。...首先指针H迭代到底如下图所示,并且设置一个新指针作为翻转链表头。由于整个链表翻转之后头就是最后一个数,所以整个过程NewH指针一直指向存放5地址空间。

1.1K20

C++【一棵红黑树封装 set 和 map】

,当整棵树都重构完成返回 根节点 注意: 拷贝构造函数参数需要使用 引用,避免 无穷递归问题 因为是三叉链结构,需要注意父指针链接,判断不为空直接链接即可 1.1.4、赋值重载 编译生成...树形 结构容器进行遍历时,默认按 序遍历 顺序进行迭代移动,因为这样遍历 二叉搜索树 ,结果为 有序 清楚遍历路径,就可以设计具体操作了 正向移动 operator++() 与 operator...指向,这种方法进行迭代操作时比较友好,其他场景下就比较麻烦了,需要额外维护一个节点 如果按库 红黑树定义,rbegin() 就是 header 这个节点,因为它指向 最右节点 为了避免破坏前面的操作...,否则会导致这个错误无法出现 出现错误原因 set ,普通对象调用 begin() 或 end() 时,返回是 普通迭代,但此时 iterator 是 const 迭代,这就涉及一个类型转换问题了...:不能给常量对象赋值 注意: set 普通对象对应也是 const 迭代,但底层 红黑树 仍然是普通对象,返回普通迭代无法转换为 set const 迭代,需要通过特殊构造函数解决

23130

二叉树八股文:递归迭代通用模板

首先我想说,递归迭代从实用性角度讲是没什么意义,明明可以写递归解法,为什么非要改成迭代方式?...通用性较差意思是说,模板只是针对「用迭代方式返回二叉树前//后序遍历结果」这个问题,函数签名类似这样,返回一个TreeNode列表: List traverse(TreeNode...理论上,所有递归算法都可以利用栈改成迭代形式,因为计算机本质上就是借助栈来迭代地执行递归函数。 所以本文就来利用「栈」模拟函数递归过程,总结一套二叉树通用迭代遍历框架。...假设计算机运行函数A,就会把A放到调用栈里面,如果A又调用了函数B,则把B压在A上面,如果B又调用了C,那就再把C压到B上面…… 当C执行结束,C出栈,返回值传给B,B执行完出栈,返回值传给A,最后等...其实很简单,我们只需要维护一个visited指针,指向「上一次遍历完成根节点」,就可以判断p左右子树遍历情况了 下面是迭代遍历二叉树完整代码框架: // 模拟函数调用栈 private Stack

36230

删除链表重复节点.

前言 一个排序链表,存在重复节点,如何删除链表重复节点并返回删除链表头指针?例如:1->2->3->3->4->4->5,处理后为: 1->2->5。...找到,我们将其传入递归函数,并返回这个递归函数;如果当前节点pHead与它下一个节点不等,我们就将其下一个节点传入递归函数,修改pHead下一个节点指向为此递归函数。...,寻找与当前节点不重复节点;找到后继续调用递归函数,将不重复节点作为参数传入,最后返回这个递归函数。...如果不相等,则修改pHead.next指向,使用递归函数求出当前不相等节点,最后返回pHead。...// 本轮轮递归结束,返回最终链表头节点 return pHead; } } 测试用例 我们将开头例子代入上述代码,验证下能否正确执行。

2.7K40

Java谈尾递归--尾递归和垃圾回收比较(转载)

比如如果有返回,你不能:乘个常数 return 3f(n);乘个n return n*f(n);甚至是 f(n)+f(n-1) 另外,使用return递归还跟函数式编程有一点关系 编译对尾递归优化...,不仅不用释放上一个,连下一个新都不用开,效率非常高(有人做实验,这个比递推比迭代都要效率高) 为什么写成尾递归形式,编译就能优化了?...因此,,只保存有基本类型变量和对象引用。而引用所指向对象保存在堆。...每个对象包含一个计数。当有新指向该对象引用时,计数加 1。...那为什么呢,我看到有的说法是:JAVA编写组不实现尾递归优化是觉得麻烦又没有太大必要,就懒得实现了(原话是:日程表上,但是非常靠后),官方建议是不使用递归,而是使用while循环,迭代,递推 转载

1.3K50

Python工程师必考6个经典面试题

函数tuple(seq)可以把所有可迭代(iterable)序列转换成一个tuple, 元素不变,排序也不变 list转为tuple: temp_list=[1,2,3,4,5] 将temp_list...进行强制转换:tuple(temp_list) 确定是否转换成功:print(type(temp_list)) 函数list(seq)可以把所有的序列和可迭代对象转换成一个list,元素不变,排序也不变...它们两个都在re模块 ·match()函数string开始位置匹配,如果不匹配,则返回None; ·search()会扫描整个string查找匹配; match() importre...这里还有一个问题,为什么 a 和 b 都是 “hello” 时候,a is b 返回True,而 a 和 b都是 “hello world” 时候,a is b 返回False呢?...11.例举你知道 Python 对象命名规范,例如方法或者类等 12.Python 注释有几种? 13.如何优雅给一个函数加注释? 14.如何给变量加注释?

46930

2019年,Python工程师必考6个面试题,Python面试题No5

函数tuple(seq)可以把所有可迭代(iterable)序列转换成一个tuple, 元素不变,排序也不变 list转为tuple: temp_list = [1,2,3,4,5] 将temp_list...进行强制转换:tuple(temp_list) 确定是否转换成功:print(type(temp_list)) 函数list(seq)可以把所有的序列和可迭代对象转换成一个list,元素不变,排序也不变...它们两个都在re模块 match()函数string开始位置匹配,如果不匹配,则返回None; search()会扫描整个string查找匹配; match() >>> import re >>...,用来比较判断两个对象value(值)是否相等 is也被叫做同一性运算符(对象标示符),这个运算符比较判断是对象间唯一身份标识,也就是id(内存地址)是否相同 我们检查 a is b 时候...这里还有一个问题,为什么 a 和 b 都是 "hello" 时候,a is b 返回True,而 a 和 b都是 "hello world" 时候,a is b 返回False呢?

75820

前端高频面试题(三)(附答案)

迭代查询与递归查询实际上,DNS解析是一个包含迭代查询和递归查询过程。递归查询指的是查询请求发出,域名服务代为向下一级域名服务发出请求,最后向用户返回查询最终结果。...使用递归 查询,用户只需要发出一次查询请求。迭代查询指的是查询请求,域名服务返回单次查询结果。下一级查询由用户自己请求。使用迭代查询,用户需要发出 多次查询请求。...一般我们向本地 DNS 服务发送请求方式就是递归查询,因为我们只需要发出一次请求,然后本地 DNS 服务返回给我 们最终请求结果。...而本地 DNS 服务向其他域名服务请求过程是迭代查询过程,因为每一次域名服务返回单次 查询结果,下一级查询由本地 DNS 服务自己进行。...这个时候就可以通过 response 数据来对页面进行更新了。当对象属性和监听函数设置完成,最后调用 sent 方法来向服务发起请求,可以传入参数作为发送数据体。

42120

记录我Python学习笔记

def语句,依次写出函数名、括号、括号里参数和冒号: ,然后,缩进块编写函数体,函数返回值用return语句返回。...计算机函数调用是通过栈(stack)这种数据结构实现,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈大小不是无限,所以,递归调用次数过多,会导致栈溢出。...遗憾是,大多数编程语言没有针对尾递归做优化,Python解释也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。...可以被next()函数调用并不断返回下一个值对象称为迭代:Iterator。...,返回一个函数,所以,原来now()函数仍然存在,只是现在同名now变量指向了新函数,于是调用now()将执行新函数,即在log()函数返回wrapper()函数

68620
领券