)
教程【免费下载链接】Learn-Algorithms算法学习笔记项目地址https://gitcode.com/gh_mirrors/le/Learn-Algorithms点击查看免费下载迭代法Iteration是一种不断用旧值递推新值的过程是算法设计中与递归并列的基本思维方式。本文基于 Learn-Algorithms 仓库中 迭代法.md 的骨架结合仓库内 8 Algorithms Analysis 系列笔记与 9 Algorithms Job Interview 面试题代码系统梳理迭代法的定义与分类、三大构成要素迭代变量、迭代关系、迭代过程控制、与递归的关系对比并以求方程近似根牛顿迭代法、二分迭代、幂运算、平方根判断、数组与链表遍历、排序、查找等真实代码案例展开实战讲解。读完本文你将掌握迭代法的建模步骤与终止条件设计方法能直接用 C/Java 代码实现典型的精确迭代与近似迭代算法。一、什么是迭代法定义与分类迭代法是一种不断用旧值递推新值的过程分精确迭代和近似迭代是用来求方程和方程组近似根的方法。——迭代法.md迭代法本质上是让一系列状态按照既定的规则逐步演化每一轮循环中利用当前状态旧值计算出下一轮的状态新值并将新值作为下一轮计算的输入如此反复直到满足终止条件。这个过程不需要函数自我调用而是通过循环结构显式地推进状态。1.1 精确迭代精确迭代适用于能够通过有限次递推得到确定精确结果的问题例如斐波那契数列的循环计算fib(n) fib(n-1) fib(n-2)用两个变量滚动推进幂运算的循环累乘result * base数组/链表的遍历、计数、求和排序算法中基于比较交换的多轮扫描如冒泡、选择排序二分查找中通过循环不断收缩查找区间。这类迭代的次数通常是确定的与问题规模相关结果不依赖于收敛判断一次运行即可得到最终答案。1.2 近似迭代近似迭代用于求方程和方程组的近似根其特点是迭代结果无法在有限步内得到精确值只能通过不断逼近在误差或变化量小于某个阈值时终止。典型代表是牛顿迭代法Newtons Method$$x_{n1} x_n - \frac{f(x_n)}{f(x_n)}$$从一个初始猜测值出发反复用切线近似逼近方程的根。仓库中 4.2 数值-指数.md 在求根号2的值一题中明确指出候选解法为泰勒级数与牛顿迭代法正是近似迭代的典型场景。近似迭代的核心特征是收敛性只有迭代关系设计合理、初值选取恰当序列 $x_1, x_2, \dots, x_n$ 才会收敛到目标根否则迭代可能发散或震荡永远无法终止。二、迭代法的三要素建模与设计原文档明确指出一个完整的迭代算法必须回答三个问题迭代变量确定哪些变量承载状态每轮迭代后这些变量的值会被更新。迭代关系即状态转移规则——从旧值推导新值的公式或逻辑。迭代关系选择不合理会导致迭代失败发散、死循环或结果错误。迭代过程控制确定迭代什么时候结束不能无休止进行下去。2.1 迭代变量迭代变量是迭代过程的记忆单元。例如求斐波那契数列时只需要保存前两个状态prev和curr见下文案例二分查找中保存区间端点low与high链表反转中保存三个指针prev / curr / next。变量的数量与含义直接决定迭代关系的表达能力。2.2 迭代关系迭代关系是算法的发动机必须满足两条要求正确性新值必须严格按数学或业务规则由旧值推导收敛性近似迭代映射必须能引导状态向目标逼近否则会出现发散或振荡。以牛顿迭代法求 $\sqrt{2}$ 为例构造 $f(x) x^2 - 2$迭代关系为$$x_{n1} \frac{x_n \frac{2}{x_n}}{2}$$该关系来自牛顿法的化简$x_{n1} x_n - \frac{x_n^2 - 2}{2x_n} \frac{x_n 2/x_n}{2}$。若错误地写成 $x_{n1} x_n^2 - 2$则初值 1 会得到 1 → -1 → -1 … 立即发散这正是迭代关系选择不合理导致迭代失败的直观例证。2.3 迭代过程控制终止条件设计迭代控制是防止无休止进行下去的关键常见终止条件包括终止条件类型适用场景示例固定迭代次数迭代次数可预先确定的精确迭代for (int i 0; i n; i)区间收缩到指定大小二分查找、二分法求根while (high - low eps)结果变化量小于阈值牛顿迭代、梯度下降while (fabs(xn1 - xn) 1e-6)达到边界或遍历完所有元素链表/数组遍历while (p ! NULL)条件翻转满足/不满足循环直到布尔条件成立while (sum n)特别注意两个高频错误死循环终止条件永不为真如比较方向写反、步进语句缺失过早终止/精度不足阈值 $\epsilon$ 取得过大导致近似根精度不够过小则迭代次数过多。三、迭代与递归的关系自顶向下与自底向上仓库中 递归.md 给出了精辟的总结自顶向下的递归自底向上是迭代。两者的本质联系在于任何一个可以用递归描述的过程都可以改写为迭代反之亦然。区别在于维度递归迭代实现方式函数自我调用循环结构显式推进执行方向先递推分解问题再回归组合结果自顶向下从最小状态开始自底向上逐步求解空间开销每次调用压栈深度大时可能栈溢出通常只需常量级辅助变量如 O(1)时间开销函数调用有额外开销且易产生重复计算无调用开销可控性更强典型问题树遍历、快排、归并斐波那契滚动计算、二分查找、牛顿迭代递归的运行效率相对较低因为有函数调用的开销递归多次也可能造成栈溢出递归.md迭代版本往往可以用 O(1) 空间完成同样计算。这也是为什么许多面试题如斐波那契、链表反转都要求先给出迭代解法。斐波那契数列是理解二者差异的最佳案例递归版fib(N) fib(N-1) fib(N-2)存在大量重复子问题递归树中重叠子问题呈指数膨胀而迭代版只需两个变量滚动更新时间复杂度 O(n)、空间复杂度 O(1)。四、精确迭代实战从数列到数组、链表4.1 斐波那契数列滚动变量的精确迭代仓库 5 array/fibonacci.c 同时给出了递归与循环两种实现并用clock()对fibonacci2(40)计时// 循环迭代版 int fibonacci2(int n){ int result[2] {0,1}; if ( n2 ) return result[n]; int fibOne0; int fibTwo1; int fibN; for (int i 2; i n; i){ fibN fibOne fibTwo; // 迭代关系新值 旧值之和 fibOne fibTwo; // 迭代变量更新 fibTwo fibN; } return fibN; }对照 递归.md 中给出的滚动迭代优化写法int fib(int n) { if (n 1) return 0; if (n 2 || n 1) return 1; int prev 1, curr 1; for (int i 3; i n; i) { int sum prev curr; prev curr; curr sum; } return curr; }要点拆解迭代变量prev、curr可推广到 K 阶递推时用环形数组保存最近 K 个值迭代关系fibN fibOne fibTwo过程控制i n的定长循环无需收敛判断空间优化原文档指出当前状态只和之前的两个状态有关并不需要那么长的一个 DP table 存储所有状态因此空间复杂度可降为 O(1)——这正是迭代自底向上思想的体现。4.2 幂运算快速幂的迭代化4.2 数值-指数.md 讨论了double Power(double base, int exponent)并指出朴素写法for循环连乘只考虑了exponent 0的情况未处理exponent 0与浮点判零。仓库 4 numer/Power.c 给出了快速幂的递归实现double Power(double base, int exponent){ if (exponent 0) return 1; if (exponent 1) return base; double result Power(base, exponent 1); result * result; if (exponent 1) result result*base; return result; }该递归基于a^n a^(n/2) * a^(n/2)n 为偶数、a^n a^(n/2) * a^(n/2) * an 为奇数。从自底向上是迭代的角度完全可以改写成等价的二进制扫描迭代按指数二进制位逐位平方累乘。这是精确迭代在数值计算中的典型应用。注意原文件注释也指出Power(2, -3)负数指数会出错——在工程化实现中需先处理exponent 0的取倒数分支。4.3 判断平方数循环逼近的迭代4 numer/isSquare.c 实现了一个除数递增、商随除递减、二者相遇的迭代判断int isSquare(unsigned integer){ if (integer1 || integer0) return integer; int divider2,resultinteger/divider; while(resultdivider){ divider; result integer/divider; } if (result!divider) return -1; return result; }迭代变量divider、result迭代关系divider且result integer / divider整数除法过程控制while(result divider)当商不再大于除数时停止。4.2 数值-指数.md 同时给出了更高效的二分迭代方案在[0, x]区间反复取中点平方与目标比较把区间不断减半最终落在 $\lfloor\sqrt{x}\rfloor$ 处时间复杂度 O(log n)。原文用 25 演示了 (025)/212.5 → (012)/26 → (06)/23 → (36)/24.5 → (56)/25.5 的收缩轨迹。二分迭代比线性递增更快收敛也印证了迭代关系选择决定效率。4.4 数组遍历与查找迭代的工程底色二分查找7 bianrytree/binary_search.c 中查找元素首次/末次出现位置用low/high/mid三个迭代变量在while(lowhigh)中不断收缩区间——左边界用mid (lowhigh)/2右边界用mid (lowhigh1)/2防止死循环经典的向上取整技巧。连续序列求和5 array/print_continuous_sequence_sum.c 用small/big双指针滑动窗口迭代迭代关系为sum - small; small收缩与big; sum big扩张控制条件smallbig bign/21同时内层while(sumn)负责收缩——这是迭代过程控制多层次的典型。句子按单词翻转1 string/revert_by_word.c 使用start/end双指针while(*start ! \0)与while(start end)双重循环完成整句逆序 单词逆序指针每轮移动即为迭代变量更新。4.5 链表与排序三指针迭代与多轮扫描链表反转2 链表.md 明确指出思路一迭代三个指针遍历一遍O(n) 复杂度即prev / curr / next三个迭代变量每轮完成curr.next prev后整体前移递归版虽然简洁head.next.next head但理解难度更高且存在栈深度风险。检测链表环同文档的快慢指针迭代——p1每次前进一步、p2每次前进两步若p2到达尾部则无环否则p1 p2时必然相遇。这是迭代过程控制依赖相遇这一终止条件的典型。排序的多轮扫描仓库 6 Sort 下的冒泡/选择/插入排序均为双层循环的精确迭代8.c 演示了for (int i 0; i length; i) for (j i1; j length; j)的经典双重扫描结构插入排序每轮把新元素插入已排序前缀迭代关系即从后往前比较并后移。4.6 合并有序链表迭代 vs 递归对照递归.md 给出了合并两个有序链表的递归与非递归双版本。非递归版是典型的指针迭代public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ if (l1 null) return l2; if (l2 null) return l1; LinkedNode result new LinkedNode(0); LinkedNode tmp result; while (l1 ! null l2 ! null) { if (l1.value l2.value) { tmp.next l1; tmp tmp.next; l1 l1.next; } else { tmp.next l2; l2 l2.next; tmp tmp.next; } } if (l1 ! null) tmp.next l1; if (l2 ! null) tmp.next l2; return result.next; }迭代变量tmp结果链尾指针、l1、l2两条输入链的游标迭代关系每次取两链头部较小者接到结果链尾部过程控制while (l1 ! null l2 ! null)循环结束后把剩余链整体拼接。该案例与 5.3 数列-交并集.md 中合并两个有序数列的尾部扫描写法while (index_a 0 index_b 0)从后往前放置大值互为印证迭代的关键是选对扫描方向和指针推进规则。五、近似迭代实战牛顿迭代法与二分法求根5.1 牛顿迭代法求平方根4.2 数值-指数.md 在求根号2的值并指定小数位一题中明确列出牛顿迭代法作为解法。求 $\sqrt{a}$ 等价于求 $f(x) x^2 - a 0$ 的正根牛顿迭代公式化简为$$x_{n1} \frac{x_n \frac{a}{x_n}}{2}$$伪代码可扩展为 C/Java 实现double my_sqrt(double a, double eps){ if (a 0) return -1; // 无实数根 double x a; // 迭代变量当前近似值 while (fabs(x * x - a) eps) { // 过程控制误差阈值终止 x (x a / x) / 2; // 迭代关系牛顿切线逼近 } return x; }迭代变量x当前近似根迭代关系$x_{n1} (x_n a/x_n) / 2$该关系保证二次收敛每轮有效位数约翻倍过程控制fabs(x*x - a) eps以误差阈值为终止条件若需要指定小数位输出可把阈值设为0.5 * 10^-kk 为目标小数位再对结果做定点格式化。收敛性提醒初值不宜为 0会出现除零迭代关系若写错如x x - (x*x - a)序列可能震荡或发散无法终止——这正是迭代关系选择不合理会导致迭代失败的直接体现。5.2 二分法求根区间收缩型近似迭代对单调函数 $f(x)$ 在 $[l, r]$ 内求根可用二分迭代每次取中点 $mid(lr)/2$根据 $f(mid)$ 与 0 的关系把区间减半直到区间宽度小于eps。该过程与仓库 binary_search.c 的查找首/末次出现位置完全同构迭代变量是区间端点low/high迭代关系是依据比较结果更新一侧端点过程控制是区间收缩到指定程度。二分法对迭代关系的鲁棒性要求比牛顿法低不需要导数、不会因初值发散但收敛速度线性收敛慢于牛顿法。5.3 近似迭代的工程注意事项浮点判零4.2 数值-指数.md 强调判断浮点数是否等于 0不能直接写base 0而应判断差的绝对值是否小于一个很小的范围——近似迭代的终止条件同样必须用阈值而非精确相等。最大迭代次数兜底工程中应同时设置最大迭代轮数如 1000 轮作为第二重过程控制防止收敛失败时死循环。初值选择牛顿迭代对初值敏感越接近真根收敛越快应结合问题领域给出合理初值。六、迭代法的设计套路与常见误区6.1 四步设计法抽象状态找出承载问题状态的最小变量集合迭代变量推导转移从数学递推式或业务规则写出旧值→新值的映射迭代关系设定终止确定迭代轮数/误差阈值/边界条件三者之一作为过程控制验证收敛对近似迭代用若干初值测试序列是否收敛、是否满足精度。6.2 常见误区对照表误区表现后果对策迭代关系错误转移公式写错符号/系数错结果错误或发散用数学推导校验小规模用例手算验证终止条件永不满足比较方向反、缺少步进死循环/栈溢出检查while条件是否在迭代中必然趋真必要时加轮数上限初值不当牛顿法初值为 0、负数开方除零、发散预处理边界选靠近真根的初值变量更新顺序错用已更新变量计算本轮新值结果错位如斐波那契先用旧值算出新值再统一更新浮点精确比较x 0、f(x) 0永真/永假改用阈值fabs(...) eps6.3 迭代法在仓库算法体系中的位置8 Algorithms Analysis/README.md 把迭代法与递归、分治、动态规划、回溯、穷举、贪心并列并总结贪心法、分治法、动态规划都是将问题归纳为更小的、相似的子问题通过求解子问题产生全局最优解。迭代法正是这些自顶向下策略的自底向上执行引擎动态规划动态规划.md 的状态转移方程即迭代关系的泛化DP table 填表过程就是多维迭代分治/递归递归的回归阶段可视为逆序迭代如快速幂、归并排序的合并回溯法回溯树的深度搜索常配合迭代式剪枝循环贪心法多轮局部最优选择本身就是迭代的实例化。因此在面试与工程中把递归改写成迭代如斐波那契、链表反转、二叉树遍历的显式栈迭代版是考察算法基本功的高频题其本质就是正确设计迭代变量与迭代关系。七、总结迭代法以旧值递推新值为核心由迭代变量、迭代关系、迭代过程控制三要素构成完整算法精确迭代面向结果确定的递推问题斐波那契、幂运算、遍历、排序、查找通常 O(1) 辅助空间即可完成近似迭代面向方程与方程组求根牛顿迭代法、二分法核心是设计收敛的迭代关系并设置误差阈值与轮数上限与递归互为表里——自顶向下递归、自底向上迭代二者可互相转化迭代关系选择不合理会导致迭代失败终止条件设计不当会导致死循环这两点是迭代法最容易出错的环节。参考仓库中的源码路径可继续深入迭代法.md、递归.md、README.md、4.2 数值-指数.md、5 array/fibonacci.c、4 numer/Power.c、4 numer/isSquare.c、7 bianrytree/binary_search.c、2 链表.md。赞分享教程【免费下载链接】Learn-Algorithms算法学习笔记项目地址https://gitcode.com/gh_mirrors/le/Learn-Algorithms点击查看免费下载相关推荐深度解析OCS网课助手安全防护机制5种策略防止平台检测深度解析OCS网课助手安全防护机制5种策略防止平台检测 OCS网课助手作为一款专为大学生设计的网课辅助工具支持超星学习通、知道智慧树、职教云等主流平台其核教育黑苹果配置革命10分钟告别3天折腾的智能解决方案黑苹果配置革命10分钟告别3天折腾的智能解决方案 还在为复杂的黑苹果配置而头疼吗面对海量的技术文档、复杂的硬件兼容性测试和繁琐的手动配置过程许多用户往往在开发工具CLIOpenSSL国密算法实战指南SM2/SM3/SM4深度解析与高效应用OpenSSL国密算法实战指南SM2/SM3/SM4深度解析与高效应用 在当今信息安全日益重要的时代国产密码算法已成为保障数据安全的核心技术。OpenSSL密码学网络安全通信上一篇Bernini-R-GGUF-ComfyUI安装教程5分钟快速部署AI视频生成环境下一篇Perfetto heapprofd实践指南一条命令快速定位原生内存泄漏创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考