: a% f. l; o: d 递归 vs 迭代 * F6 e. |" C9 n3 Z8 s| | 递归 | 迭代 |6 H+ `' n; X U9 d8 u5 J
|----------|-----------------------------|------------------| 9 |, B4 b& {# U# |% p2 i& K: B| 实现方式 | 函数自调用 | 循环结构 |! z) z% b1 b; B2 z6 U2 \# u0 i' z
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |. X% Q0 a) E& V8 J/ a, \$ @" B
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | , W9 w0 {4 s, {/ _- F s| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | # w9 A/ _" s8 t/ ]2 t8 ]' x" F; ]+ H) G0 ~5 i/ `
经典递归应用场景3 L9 v" ~1 L8 V: J, |
1. 文件系统遍历(目录树结构)) L" c8 }% I! v% _! z* |, f7 g
2. 快速排序/归并排序算法7 }; \! ~1 x3 M, s
3. 汉诺塔问题 & O( ?% T; [0 y5 g2 l; {. d4. 二叉树遍历(前序/中序/后序)* T" B0 e: x8 X8 _! N* e6 L
5. 生成所有可能的组合(回溯算法) & j$ d7 o' W/ s2 k ! Q% [$ D7 H% Z) x) w2 D4 ~! R试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, % P- R) g6 Z. Q* `( `2 t我推理机的核心算法应该是二叉树遍历的变种。1 N$ `! \. k* Y2 L' |( [, T1 q
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过10层的,如果输入变量多的话,搜索宽度很大,但对那时的286-386DOS系统,计算压力也不算大。作者: nanimarcus 时间: 2025-2-2 00:45
Recursion in programming is a technique where a function calls itself in order to solve a problem. It is a powerful concept that allows you to break down complex problems into smaller, more manageable subproblems. Here's a detailed explanation:" V4 z, ~" ^. ^
Key Idea of Recursion! K& g! @: _8 i
$ B7 S; D% y% Q4 u+ E
A recursive function solves a problem by: $ S' o) t& O" F. q) q4 g$ t6 X F: y8 O0 m
Breaking the problem into smaller instances of the same problem. + d% J3 E S2 c) x( d& K* v& }3 c8 i) n! q, V5 }
Solving the smallest instance directly (base case).2 M7 E9 ]4 |& N# W( C U7 u0 r
o" `. Y9 y. M Combining the results of smaller instances to solve the larger problem. X3 x3 L2 y3 u0 ^6 n' f# Q0 g
F4 y, j8 a+ c* ?, e, g
Components of a Recursive Function ( h( U( o) `, P6 K# c2 j , ^7 v2 S0 j4 [4 m$ T8 r Base Case:! d2 W% g) Y, j$ }: @
3 I- K/ {* ^# I$ Q, L
This is the simplest, smallest instance of the problem that can be solved directly without further recursion.3 f I. D K+ p5 b" M0 N
7 U3 N8 k1 _1 R3 D4 {% R: `! ] It acts as the stopping condition to prevent infinite recursion. " w6 h6 ? L J6 G - ]; W7 q2 r* S- S! e Example: In calculating the factorial of a number, the base case is factorial(0) = 1. o, I6 `( Q8 F4 i! y; x/ W 2 G* D( Z% e W& |" j+ | Recursive Case: . J2 _2 M( M& @: {. B1 n% ^* |/ F" W. O1 G& O7 i# K8 A0 L
This is where the function calls itself with a smaller or simpler version of the problem. & w' W" m3 \" n1 R! q ; N2 A3 q4 G. n Z Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). 3 b l6 h3 c9 F3 W+ x . v9 G" J- @0 D2 _ M' jExample: Factorial Calculation9 E0 g$ B/ J0 N% S
% v7 Z" {, W3 D3 w* B) pThe factorial of a number n (denoted as n!) is the product of all positive integers less than or equal to n. It can be defined recursively as: / ?7 \; D8 [# A( W, ~) M . V2 g- h/ g4 U. v/ ~: N- w! n Base case: 0! = 1) I7 g( q$ I$ w, e: H+ J" f
* T% R" W8 x1 p' r, }. A2 d0 M% g Recursive case: n! = n * (n-1)!9 V1 V9 U& S, K1 m$ C
# S; C# q: m$ t7 B# Y8 g
Here’s how it looks in code (Python): 2 E. `; E# c) s2 K& Cpython6 ~9 M7 z2 H/ m$ K3 T" P
0 b c- v) l7 q
) X; E5 t+ @ p4 h! O
def factorial(n): ( A- Y1 Y* s! O6 H8 O3 p% b+ j # Base case 0 [9 }. ~; h, d if n == 0: 6 N1 `) J& N/ Q( a$ t* B return 1' `8 R6 X1 r5 h2 T+ l) _) ^
# Recursive case/ j1 h+ u1 O M2 {# G s- S0 ]7 w
else: & C* J% x/ I1 M# z4 t3 J return n * factorial(n - 1) ( [4 E, f S! r* ^ {# { p, C 8 O& a. b- v1 X* k4 z! m# Example usage* c% D8 t" v5 Z& w3 b
print(factorial(5)) # Output: 120& L5 P. y/ l+ t6 |1 h
4 `! u* A1 Q! a* h- N
How Recursion Works4 e* r/ n& C6 U/ A6 X/ B, ~
/ K9 r- z5 L S, {
The function keeps calling itself with smaller inputs until it reaches the base case.4 [( I/ E* K* R1 H( t- e. ]
9 ?1 Q( j, U) Y, e+ ] Once the base case is reached, the function starts returning values back up the call stack. ' x n# H% Y4 B/ C0 s8 S9 o+ k2 O) E X% J! ]7 J9 _( y
These returned values are combined to produce the final result. $ C0 @' G3 b3 v0 B + D4 W/ n/ N6 X# `For factorial(5): 6 y2 O u, h" W! a8 o & W7 h& d; ] a7 ^" y* U! a. J1 f4 e6 P2 Y
factorial(5) = 5 * factorial(4) / l! [' D4 K+ W) U B u0 T' {& afactorial(4) = 4 * factorial(3) 8 h8 p: X! _8 r6 i* Afactorial(3) = 3 * factorial(2)5 O0 j+ W" n+ Y$ S2 m* K
factorial(2) = 2 * factorial(1) 0 `; m! o \# o; ?* W7 yfactorial(1) = 1 * factorial(0) 9 }" X* [$ H/ u* }1 sfactorial(0) = 1 # Base case 9 T/ T3 R6 O# T2 R $ G* @6 ], O# b wThen, the results are combined: 5 r8 w& P4 n$ M: I8 e5 [' T3 ]1 B: P; D* U8 S p* n O& [
, V6 ?! _& o6 Z/ G
factorial(1) = 1 * 1 = 12 n; Y7 x& v# q- |, {
factorial(2) = 2 * 1 = 21 v G' \8 I# s
factorial(3) = 3 * 2 = 6& E) U/ F2 W: K. o* m
factorial(4) = 4 * 6 = 240 n1 c1 {7 L& S/ F# ? p
factorial(5) = 5 * 24 = 120 " M) d: G: i7 S+ K2 a3 O! O/ Y: W% T4 z! y# t' H$ y
Advantages of Recursion m1 k9 ], m3 ]# R9 \! N4 u8 L3 Z4 j3 Y! }
Simplicity: Recursive solutions are often more intuitive and easier to write for problems that have a natural recursive structure (e.g., tree traversals, divide-and-conquer algorithms). Q3 {* K7 A1 A+ y
' ]- E6 }9 } E: c
Readability: Recursive code can be more readable and concise compared to iterative solutions.; `1 k0 v- c& y2 B
5 w% F0 }9 y- S9 Z4 a/ @! F! G( E6 pDisadvantages of Recursion # T5 |* X+ A9 d& Y& c2 ~$ Y3 N $ K" W, H6 J1 G( @8 { Performance Overhead: Each recursive call adds a new layer to the call stack, which can lead to high memory usage and potential stack overflow for deep recursion.# H# V& \7 ^) [
% G* r/ i ?5 b' g- c$ k# D: Z
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). ! |4 `! N$ j( S% s * M& Q7 h8 w/ S$ vWhen to Use Recursion! l. f7 }7 a- d7 C" `
- |) }; ~5 x' E: W' ?* } Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). 0 _4 y5 A: L- t; J. A( x8 }$ B/ x* s* G+ v/ L; f4 C( _
Problems with a clear base case and recursive case. + A9 o$ x4 `; `1 O; J* V6 y. z' V7 z& k: s! T& O" Y8 j
Example: Fibonacci Sequence % Z+ z9 g; w- K% P1 d+ X+ f9 p9 L; H7 ?# C" o6 k
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: % G# W; s, P# `* s9 Z i 7 p9 |8 q: v7 D: x1 ~ Base case: fib(0) = 0, fib(1) = 1; L2 N. ^& G/ F* _
4 M8 j v; x* |5 a, x# p8 T H
Recursive case: fib(n) = fib(n-1) + fib(n-2) ; H! v0 D% z6 s$ d( a! N* T/ V1 h2 t' h$ L. K
python 2 G+ O2 P5 E* `6 N V * d$ v$ j, I$ M% B6 _2 @ . O( O5 c2 ?( @2 ~( b* Fdef fibonacci(n): 1 T: ?& `9 b# O5 e # Base cases ) L' z: R$ P0 g! ] if n == 0: % Y- |$ w s! j$ h return 0 2 M$ d0 A7 d+ G elif n == 1: 1 ]5 A" s! D( A7 T' p return 1$ p$ x9 k, O- s D1 ~+ O9 p; v1 m( `4 {
# Recursive case 2 R7 i4 W+ c# O. Y else:. S$ r. Y1 s7 I+ V
return fibonacci(n - 1) + fibonacci(n - 2). v. t z+ B- V1 |
. Y6 {8 X1 n N7 }# Example usage 2 V5 d5 ~1 T& H; q* X3 K* sprint(fibonacci(6)) # Output: 8 : ?5 c: `1 E# ~$ M2 h6 P0 E9 _+ a ( f+ D% z/ V7 n; |Tail Recursion) a8 ~& N* R; L2 a' V
" L4 D# r( A D' N% ZTail recursion is a special case of recursion where the recursive call is the last operation in the function. Some programming languages optimize tail-recursive functions to avoid stack overflow, but not all languages (e.g., Python does not optimize tail recursion).; \% u$ @( n: }. v
/ ~) A6 {* m3 D% p% uIn summary, recursion is a fundamental concept in programming that allows you to solve problems by breaking them into smaller, self-similar subproblems. It’s important to define a base case to avoid infinite recursion and to understand the trade-offs between recursion and iteration.作者: nanimarcus 时间: 2025-2-2 00:47
我还让Deepseek 给我讲讲Linux Kernel Driver 现在的开发流程,让一个老同志复习复习,快忘光了。