' a$ Z; W: p" |+ v3 \) M* B% i0 F 递归 vs 迭代" C. K4 L. D5 F1 U5 U
| | 递归 | 迭代 |0 ^" ]! v5 M9 S/ h j1 j
|----------|-----------------------------|------------------| 2 S) Y M+ ]# g ?( r0 u2 q* |& d| 实现方式 | 函数自调用 | 循环结构 | : }" e5 M$ Z# L( G1 v& @7 C( l0 M| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 3 @' ]/ I3 y8 q7 {( ]| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |+ [! N: s2 P; {# L: ^
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | ) e' j+ h; f3 u0 J; L' e7 g. G: u4 q2 c. t
经典递归应用场景 5 M2 L, M- ~9 P7 G4 g1 I1. 文件系统遍历(目录树结构)" \% e4 h; j1 f7 H
2. 快速排序/归并排序算法( J3 h# x% j! t. d; r- I4 f; @- U
3. 汉诺塔问题 6 N8 d9 l# W! X4. 二叉树遍历(前序/中序/后序)) @( d* M a, c2 R5 k: g4 X
5. 生成所有可能的组合(回溯算法)3 h1 W' Q0 X _! G1 P8 N8 f
! h% s0 s0 O9 J) @
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, 8 G& @" X) R+ r3 e# Y我推理机的核心算法应该是二叉树遍历的变种。! d: q' i5 d% b! t
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: 1 I& C! [3 F+ B+ B0 KKey Idea of Recursion $ {; h6 @# U6 o" H# w$ a; S 3 ^, E- v" @( t+ r7 F. T8 c; gA recursive function solves a problem by: 6 L/ W- A: e2 g% o1 w2 ^ ) g) Z" _8 D1 T/ y9 p o6 \8 t Breaking the problem into smaller instances of the same problem. $ X+ `/ @9 S$ D* r/ \. W/ K* {6 O2 `4 r k
Solving the smallest instance directly (base case).8 ^1 B4 G( B; w, s$ z; i
% ^) P8 x) y6 u* i1 u) } Combining the results of smaller instances to solve the larger problem.0 ?# ]3 o( W. s$ [: m" S+ Y9 ?! M
7 g" z* i& K( p |2 {2 G7 b8 R3 OComponents of a Recursive Function, D# L# _+ `( B$ {* R) h
* p& M/ x4 f5 _1 X6 o Base Case: # g- E/ c; L3 u5 ~ " `" @ ^/ w0 d5 G, k b& q& `$ J This is the simplest, smallest instance of the problem that can be solved directly without further recursion.4 m( N( p5 v' R3 t; `
1 B0 N& J9 B' j; W2 O" @" m/ M
It acts as the stopping condition to prevent infinite recursion. , ~( k" ~ Q5 k9 n+ M8 t. i4 h # ]- k$ {/ g) t# H, j9 Z p0 Z Example: In calculating the factorial of a number, the base case is factorial(0) = 1. $ @5 L! a: R; N2 }+ Q# W& P* o0 h7 y1 `5 {: M2 R$ ?3 M* A5 m! }! }' u
Recursive Case: ! j o, Y5 w( b5 M: O( e5 \. \, v3 c0 S6 u
This is where the function calls itself with a smaller or simpler version of the problem. 1 [' s6 i5 q) z7 }/ x6 _( \' E7 u
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). 0 ~' D7 R3 L9 v# p/ J" Z9 ]- @( v3 `* Z$ c% w5 `9 d
Example: Factorial Calculation 7 U- y6 f2 t2 ~8 A6 i 5 \ i& `. w* H" Y' y, P5 [+ {5 Y; r8 kThe 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:+ K8 r' o1 R# u8 L! \
3 H9 y# e% T4 P0 V3 y) W _$ K Base case: 0! = 1 2 T L6 e# Y+ g5 ?( F# [. j/ p8 Q: a
Recursive case: n! = n * (n-1)! 4 V- D( r+ v+ W+ u$ h' o. G! N$ U: B; @, v* T' Z( d9 a9 r' ?
Here’s how it looks in code (Python):/ N* X1 J3 W$ n. J3 g
python' b6 r* v- M% e0 j7 ]7 J
9 ?" @% S( ]3 e$ a( n' f6 r# ^2 H' |/ C$ B7 ]
def factorial(n): $ {. \& f$ m3 \* Z! _2 j # Base case # J! I. }9 W) ]- m if n == 0: " u4 C9 j5 u+ o return 1 5 w+ k) }7 `7 H( m# b+ \ # Recursive case ; h( I- G. j9 [" T/ X3 g else: ; y- L) D: N3 x8 I return n * factorial(n - 1); p, g* B3 n! g( q7 |* H
/ P; h- f& z3 i" ~6 [# Example usage - J( ?, g+ g* p+ C8 {print(factorial(5)) # Output: 120 $ p; E. \* w& V3 \; _" L0 {% \+ f* h9 p- d% T- E& ?
How Recursion Works, @& f. T# O, I7 v, r3 f
3 H+ }3 O2 o' g' a; u( G
The function keeps calling itself with smaller inputs until it reaches the base case. % `7 W4 z$ t# E+ A# a5 \3 S, ?) v, J2 g: \2 Y* x, j7 u- G( p( t
Once the base case is reached, the function starts returning values back up the call stack.0 y. n# k3 b7 |& A" b! t
n3 O% z9 S- ?: ^
These returned values are combined to produce the final result.+ _1 s0 @% T+ i1 Z6 ^9 @
1 u' q2 l% j( lFor factorial(5): ! H+ H: n [9 C% L ; g: f, w5 f+ y8 Q : e$ d x- P* V" Mfactorial(5) = 5 * factorial(4) + U/ X; C0 H$ v9 zfactorial(4) = 4 * factorial(3) % {3 a4 T) @% y$ I- Rfactorial(3) = 3 * factorial(2)# Q p( G+ p. e. _
factorial(2) = 2 * factorial(1)- o8 K/ Y$ `" `# ~% ^
factorial(1) = 1 * factorial(0) % V1 g% |. B _' rfactorial(0) = 1 # Base case7 l$ P7 o# z3 j% c, E
( W- E; q# K+ H. ]" H$ \
Then, the results are combined: / q' M+ n R% ]0 H9 E, D 4 e9 s6 K T( e ]8 u% L9 X# D' Y, l5 C; S P! {/ n
factorial(1) = 1 * 1 = 1, E, t3 R% e, }$ _" Z. b
factorial(2) = 2 * 1 = 2- J7 u) N7 b8 W [ x, n
factorial(3) = 3 * 2 = 6: i8 r( x- u- ?+ T) a M
factorial(4) = 4 * 6 = 24. C' c" f- n4 S
factorial(5) = 5 * 24 = 120 t3 j! v, z; ?& U8 c & I# t) g1 {- B# T$ n3 R6 IAdvantages of Recursion 9 i: O- j: d2 {$ \/ n: o + }. w9 D$ K1 Y/ j7 N, p 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).: O/ N8 t; s3 |" Q
6 Z, @( s9 X+ Z- e! i: ]. l
Readability: Recursive code can be more readable and concise compared to iterative solutions.* R- r7 C" W5 g4 d: R
3 ^, [/ U$ w3 Q5 wDisadvantages of Recursion' v3 ~- b% l9 S' A& b) v& B, k" G; Y
2 L `: o- k% F. I+ i: ^ 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. ) L( S. U8 w: s3 G* | w4 E( C" P" Q! T
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).( S" u3 _$ e+ A# p7 N! X+ @, |1 ^. V
4 e; p/ Y( B! l H5 o
When to Use Recursion : s& y+ F+ A( J1 S$ ~ c7 g( M) p; O/ x* G Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). + _: K3 W- N) j) w# [" X0 i/ e( |( p0 K
Problems with a clear base case and recursive case., I4 i; G f9 d" y, Q, ^4 e# }
+ w% o( o% \ b* J/ I( S
Example: Fibonacci Sequence' \7 i- C2 U: ^3 i
* v; w9 ?4 N; p4 c- N+ R H7 @
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: % ~7 E# T+ y8 W5 ?4 G , h6 J0 y( i ~4 |2 F Base case: fib(0) = 0, fib(1) = 1) ^$ d( ` V* C* H; L' F
! E0 Z+ [/ J7 H f* I. H- x
Recursive case: fib(n) = fib(n-1) + fib(n-2) ) A/ I: Z, {9 |* }, E/ y : p1 g/ ]: D d6 p$ T, C+ bpython; d, y; `# I" m
. Y% X' ~5 m6 I7 l6 _
( s- c; e Z( j: c r( O! V8 Z) J* k6 o
def fibonacci(n): 7 B2 |9 ]' c1 h. V # Base cases1 o- f5 c4 ]. f& g) n, x
if n == 0:3 N! }3 ]1 E4 u% d
return 03 O c8 l( H7 N( V$ i
elif n == 1: 8 o! L9 k: h) H, I return 15 M# V" [# d% K$ S b9 T
# Recursive case 7 w$ x1 n+ G/ N f6 L) P else:, p3 C X, b. H" e% o
return fibonacci(n - 1) + fibonacci(n - 2) 7 d1 x* B7 i, ` + s$ j! d! o5 v; z4 K) C$ A/ B# Example usage e3 E! L1 P6 m# ^9 W7 W2 x
print(fibonacci(6)) # Output: 8- x- g- n3 R& O L' X4 p, l
2 I- W% U- _9 e; mTail Recursion 7 k1 D! M. K+ E+ e . E, q7 g' r5 F* \Tail 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). 1 w/ F; a5 |- {% E" b: L- _! X) m ( ^; P b' O. t7 y8 L- @In 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 现在的开发流程,让一个老同志复习复习,快忘光了。