) j/ q/ z, q; O" e 关键要素. j" x5 Q7 H! u1 O$ M
1. **基线条件(Base Case)**1 B3 |& X* {+ x1 Y6 }1 p/ p9 N
- 递归终止的条件,防止无限循环2 Z5 C$ R/ O$ l5 j1 u2 ]: o
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 18 b& J: Y/ c0 f1 H0 M
: ~; a7 W' y' Q7 b+ u: ~8 t$ w2. **递归条件(Recursive Case)**. ?0 {& V( \$ q
- 将原问题分解为更小的子问题* u; U2 Q" R2 f1 V/ \# p- ]$ r6 ^8 q
- 例如:n! = n × (n-1)!7 S. e% }8 q0 M( H! e
* W& Z* u% D s3 ^+ `& v3 U 经典示例:计算阶乘 4 s# Q0 c" N* Y+ g ^4 @python : `* s$ p. l' L7 F' sdef factorial(n): $ F; V) ~4 ]+ W. N if n == 0: # 基线条件 # Q1 V4 O/ S8 j+ V% ^! ^3 ?& ? return 1$ y% b$ }5 C- B, S
else: # 递归条件 * Z. x% _9 G5 p, I/ O6 l return n * factorial(n-1)5 F4 S( ~4 C( D# g3 ]
执行过程(以计算 3! 为例):2 P' n; w' W! m$ o
factorial(3)1 b0 m4 t4 D/ \
3 * factorial(2) 0 G$ M; Z5 p) U0 _- M/ y3 * (2 * factorial(1))# r. K3 G; }0 |
3 * (2 * (1 * factorial(0)))9 _$ [) S0 _' b+ H* b* Y
3 * (2 * (1 * 1)) = 6" B' K! t9 f) X& f
0 k( w( l, \( f: d( P5 A" {$ [$ K. z
递归思维要点5 j# y& ]8 E3 r* X8 W* A) g4 ^
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 8 A# G- {% l" C6 I' t. q& c2. **栈结构**:每次调用都会创建新的栈帧(内存空间) 5 Q+ Q8 u- B3 ]1 F' B3. **递推过程**:不断向下分解问题(递)' P8 ~' T1 W/ S$ I
4. **回溯过程**:组合子问题结果返回(归) & f, }/ ~# m4 v$ R3 z; O( L & z) z% F' J: ] 注意事项 ! v' b$ Z4 y8 p& |3 T必须要有终止条件: |0 F* V( N5 D# W1 T/ S3 n
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) ( K* t$ L/ u$ v3 r某些问题用递归更直观(如树遍历),但效率可能不如迭代 3 t: R3 Z) ~' b4 }' Z尾递归优化可以提升效率(但Python不支持) - ?1 D2 ?) g6 P7 \3 L% o2 v) f4 H4 u0 p' w: N. ]1 ^
递归 vs 迭代 ) }- ?( ?. S' z2 J. p| | 递归 | 迭代 |1 H( n! J& |6 w& q# O
|----------|-----------------------------|------------------|. S+ e* M, a, [6 L2 j+ ]" P) P' |& r
| 实现方式 | 函数自调用 | 循环结构 | ; n# D( E) ]! S* b8 P| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 5 W; P8 F! c& L| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | . j5 ?) }; ^! m% @, `' o# P0 O, S| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | p/ U* p1 z* Z # s' E$ N* N: V3 ^ 经典递归应用场景 8 G, s' J8 i. Q0 k1 s0 M: X# E: H1. 文件系统遍历(目录树结构) 2 w0 z0 {: w9 r; a& w" N9 B2. 快速排序/归并排序算法& u* p. \8 Q2 N- n8 X+ F) e0 Q
3. 汉诺塔问题: A- Y0 X; j3 L
4. 二叉树遍历(前序/中序/后序)9 W& D% }& I8 Q8 ?" c# d$ V) l
5. 生成所有可能的组合(回溯算法)- S1 _+ Y4 W. }* S+ d
2 }9 l* i# G! [9 b' S2 E: I5 j2 Y试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, $ J+ Z' z' m" t: C! Z我推理机的核心算法应该是二叉树遍历的变种。 , R: U i' H3 s另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:5 T( o( F4 o9 Y: s1 }. c3 q) \! O
Key Idea of Recursion 3 o9 G9 }1 D6 B4 ]6 ~3 G1 X" N' A* C3 w" R% D1 U
A recursive function solves a problem by: 1 ~- i/ b3 \8 z3 ?3 s. D y% E+ P5 y2 i- {; F7 c$ ~4 X
Breaking the problem into smaller instances of the same problem. * R* t; `: {( ?' u0 f8 f ! ~+ o; x8 W, c2 h& @" t% C% v Solving the smallest instance directly (base case). ' {& K% a+ \ C+ o# b! ?- f" X- ?. g* N' {
Combining the results of smaller instances to solve the larger problem.- _4 T" s3 V, c! c5 O
0 @) i8 q# B! L4 D. [. \4 [! D: s
Components of a Recursive Function + h6 j) t! Q% y" N* @. k! ?$ e/ N) g8 A* k
Base Case: . q( F: c \2 k! h' l, ? 6 U8 D X1 T* ^/ i( P# M/ h This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 5 @. E2 ^- d' I* c, W" B* m" A4 r9 M# |% [0 r. Y
It acts as the stopping condition to prevent infinite recursion. 1 ]6 d2 L' s, q. a1 R) d 6 y L5 l7 ^7 N9 F' q Example: In calculating the factorial of a number, the base case is factorial(0) = 1.# k' Y0 W" O6 ~2 ]6 g4 B, m
" \5 Q/ u# C) a# G# ?/ N& U
Recursive Case: X, R0 l0 ^6 q! s7 K# x ; K0 }& z V6 W G: p5 ? This is where the function calls itself with a smaller or simpler version of the problem.+ n0 ?& _4 m7 _4 t
4 C0 y3 z3 B0 ^2 j
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). 4 T3 M$ V: F3 `8 g# R" e& o4 Z. c' H) ]) J& N! z4 D: i1 Z
Example: Factorial Calculation 2 K& b9 i1 `5 g7 a ! x1 b( V3 ^6 E$ p* S# R3 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: # a& d; b. [! p- s) [0 V 9 Z1 u1 n f. e$ W# [5 p% H% V( j Base case: 0! = 1 6 I" c" d \9 {( m! u# D1 A" B" U* u5 ^% J4 g) A7 K& j
Recursive case: n! = n * (n-1)!0 g5 M3 y5 `) y' h
/ q2 p' t7 A: N) b, p, {Here’s how it looks in code (Python): 3 u+ A$ p4 {2 t5 ~$ l, vpython" N5 H" P/ ?6 c3 [% z4 Y4 a2 m) S, D
2 i! U: T! C1 V) M; r# f. P 2 T1 L4 q, ]& b) e6 xdef factorial(n):$ B; {$ i0 k" P. u0 e# `! \
# Base case 2 E; \( q; R% L5 } if n == 0: - m# D8 I0 J1 H return 1 6 ]9 Q1 t1 Z8 Q9 H+ r+ m/ u+ h # Recursive case! v5 D5 {9 X4 _, G8 b& y
else:/ A& w- [/ r; d7 D
return n * factorial(n - 1)* i- r" D; }6 q3 \1 ^; n( P5 i
4 n0 Q& N- A! E8 O. VHow Recursion Works9 M" @ s0 C. @" b
) E( ?9 w. z. s; t- ] The function keeps calling itself with smaller inputs until it reaches the base case. * ?$ I+ p! [, x- R) M 9 w, p8 M: h* \- ?0 N0 [1 F3 | Once the base case is reached, the function starts returning values back up the call stack. 3 g# d1 e. w/ G0 u3 ~5 i2 G1 i+ m- \! F* P+ J2 V- z
These returned values are combined to produce the final result.2 N# E& u! ]4 K% ~: k
# s, F7 R' d$ A h) s- I4 Y
For factorial(5):7 N2 a" A+ ^! _9 J3 o. A% V6 v
! N0 a; W% S. L' D& W* k
& ~. I7 z8 O6 ~$ b3 @3 n; p
factorial(5) = 5 * factorial(4)/ q2 ?3 G7 O, v; v( x
factorial(4) = 4 * factorial(3) 6 N }/ _# i* K- c6 _factorial(3) = 3 * factorial(2)9 k8 P: m& u; o
factorial(2) = 2 * factorial(1) 3 E1 T, c+ Z' W& n! Yfactorial(1) = 1 * factorial(0) 7 s* i$ N8 X; ?3 c) efactorial(0) = 1 # Base case / q6 z3 q8 M5 U3 U , W' Q" h9 p- |* I9 k% BThen, the results are combined:- x% K& k0 I% {3 u" B
- J) }+ v8 W' r# D ( o' W" V3 M4 J' @8 Nfactorial(1) = 1 * 1 = 1 : ^5 D/ W; P. F5 ~5 gfactorial(2) = 2 * 1 = 2 # A5 a; ]* M6 Q& Mfactorial(3) = 3 * 2 = 65 x+ Z. p, q! C+ m& p; R
factorial(4) = 4 * 6 = 24 3 w$ ~0 {) q( u) z! ?factorial(5) = 5 * 24 = 120 % C! I; y1 t' p7 p3 f* {: o' o + v o) t( Z9 X2 a( \, O% jAdvantages of Recursion 8 Y( H; `5 i: `* [6 U2 V' ^5 Z: @& L3 a1 }
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).* W. e, E; e/ F# x
5 b% F& p* O7 E/ s
Readability: Recursive code can be more readable and concise compared to iterative solutions. 4 i7 H5 h( w: ^" s: N8 p% G9 p8 D; s* m) {
Disadvantages of Recursion' q6 a8 X( H7 ~& p
: g8 l$ V D; k+ v# E, _# u" ] 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. ) `7 _4 P; Y. k: z7 |8 Q$ t2 _1 a. H; S7 B2 K Z& h
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).% @( i' C2 t f0 V/ O3 [; U
0 g* A' }4 @ p$ C7 H7 c
When to Use Recursion( Y4 b% ^( [6 e T& b" P
; L N% [" ]. [' L1 }
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort)., i5 E9 |% s7 d6 h) g1 [
7 q+ A' t: N+ H( m; e9 L0 W: Z Problems with a clear base case and recursive case. - U/ a* U z$ K" ?9 E + T) B g/ B' r$ Q& kExample: Fibonacci Sequence 8 ^: q" X" Z3 f8 t- ?& R, |* @. D z" ^. [% m' n- A
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: & d" W" N4 ~$ ?5 t4 u( p7 \. M6 H4 f, q, }9 @: c. E0 q
Base case: fib(0) = 0, fib(1) = 1/ u, ]8 R; y* `
& D8 i. E: K1 Z" b3 x: t4 @6 X0 X
Recursive case: fib(n) = fib(n-1) + fib(n-2) ; G2 v! t$ e" \5 E 3 g/ I" K( @4 X: Y* \( J' vpython , G; s J2 e W5 w9 V$ ^ - ?- X1 a% e/ }# f% E- c% C% s / v% l- ^9 z. a; ^def fibonacci(n): # d& M: m6 ^& |5 v% V # Base cases2 K" C5 D& C T5 | l
if n == 0: ) _% y( C" F5 H, o' k% } return 0% v, A) r5 M0 P, x0 a
elif n == 1:" c* B$ E* V$ }1 F! J q
return 1& O* N G) l6 ]+ t3 D
# Recursive case 8 V( D0 n6 a3 s% Q" A% M3 D5 l else:- C3 c, z2 s1 k& {% X5 F
return fibonacci(n - 1) + fibonacci(n - 2)" Q% |; u1 G7 u4 T
, f0 u. ~; L& m5 n& m# Example usage" z3 J( P* u* e+ Y. z
print(fibonacci(6)) # Output: 8 " G+ I% q/ t \# a$ K' Q/ m ) l4 Q, V k: q- aTail Recursion ( r3 o5 b4 v1 ~; i8 B K 3 K6 T) u4 k8 Q" p) l" ]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).+ p9 \9 ` k: J1 W
* N) x6 p4 s# S& |; b: |0 E b, [- ]
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 现在的开发流程,让一个老同志复习复习,快忘光了。