. R+ _" B" W H. A8 ^. F解释的不错5 y( u) R8 \! h: q* i& \7 U" |
3 |9 q9 v! q& R; X& g* l- D- q2 \; t递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 B3 k' X l I( q' S/ j( `# k, d1 H9 l' ]
关键要素 # }% n* R- z, l ~! Q9 d& K1. **基线条件(Base Case)**9 J" b! p/ ?/ O( p
- 递归终止的条件,防止无限循环 7 A3 z' z3 ^) F* J% @ - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 $ H$ ]9 z/ Z ?2 p- ]* k* e : {1 N B. G% d! D2. **递归条件(Recursive Case)** ; p+ _! \! A) q. x H- |* p% {5 X - 将原问题分解为更小的子问题2 n# y4 N! g9 f2 g) ~ y B
- 例如:n! = n × (n-1)!9 F: B' b/ ?( f
3 G" C* |" Z+ b. D z1 l) l- E. o 经典示例:计算阶乘+ ]0 \* |: E% B, h y1 L
python# S* I$ q1 x; R" z
def factorial(n): ) X( I% |9 E! ~" i: n+ M if n == 0: # 基线条件% M+ _! J @* Q5 o L9 x* D7 I2 L
return 1/ {8 q# j0 i8 I7 q' m) C
else: # 递归条件 8 n- \4 P" z6 M. M! w return n * factorial(n-1) * D3 ]- o- o) s0 Q) f执行过程(以计算 3! 为例):2 i0 Y8 l+ n _: {
factorial(3) " H# ]7 l! t+ z! g4 z y3 * factorial(2) 9 D+ c1 G( U: U3 * (2 * factorial(1)) Z% t& L2 f8 [$ V( k b3 * (2 * (1 * factorial(0)))+ ? N5 b+ i/ I2 Q1 x1 d5 x9 W
3 * (2 * (1 * 1)) = 6' c% _( Q/ Q! ?2 P- a
' g: o& [; q3 {. B" {' J" U
递归思维要点4 S& Z! P6 \! b K
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 $ V. U L3 O( f& S4 v1 O, Y2. **栈结构**:每次调用都会创建新的栈帧(内存空间)' |3 ~0 v$ ]4 y% h! [) d) p
3. **递推过程**:不断向下分解问题(递)0 C" c+ o8 R t7 h1 n
4. **回溯过程**:组合子问题结果返回(归)7 s- z" g' R9 F# j1 {4 {" m' _3 D; d
7 x" Q* c: d! b" i 注意事项7 }. }1 ~. O& f! ^, B+ I
必须要有终止条件: V% e( E% D( r. f* h, Y9 d7 F1 R! I/ A
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)2 ^6 f7 R4 b& o. S5 F
某些问题用递归更直观(如树遍历),但效率可能不如迭代. B+ w2 n1 D U; S! @
尾递归优化可以提升效率(但Python不支持)6 m* A" Y- S: ? b0 b9 |
9 O& S# i+ s% l
递归 vs 迭代9 r! g: j$ ?7 P2 C
| | 递归 | 迭代 |) w( E: d5 z8 n0 c
|----------|-----------------------------|------------------| " l4 W4 _" ], N$ A2 z| 实现方式 | 函数自调用 | 循环结构 | 7 {; O, k1 X5 u4 i, m| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | ! z; V+ ~3 S2 v) X% y/ r. l% O1 v| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |3 R, k3 o8 w( ]
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | 5 T2 ?8 W$ e3 G/ l- Y: I 9 B8 @. Z( r1 | 经典递归应用场景 $ }+ ^, J% c, L6 q" i$ u2 X: [1. 文件系统遍历(目录树结构) ( S; b" a( c% C: T+ v, T2. 快速排序/归并排序算法' E, ?7 \, y' k+ N
3. 汉诺塔问题 : }. L- v6 ?% j1 u/ b6 m4. 二叉树遍历(前序/中序/后序). Z) p \9 v* H1 C+ ^
5. 生成所有可能的组合(回溯算法) 4 E3 w3 R: n; C2 C. a+ l# d2 [9 T) J* F; p
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,* z. B$ g! i$ a
我推理机的核心算法应该是二叉树遍历的变种。 % d0 C6 F! B3 F, _% r/ V6 _! n另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: . E3 b; [2 R, F, Y" `; G; hKey Idea of Recursion 2 O/ J. R/ a: \' m# Z6 M 1 \8 y9 f% u1 V c( N nA recursive function solves a problem by:$ E2 v, m! }0 ]/ ^8 R
0 c1 T) f3 v2 q. r! _/ p& \5 q
Breaking the problem into smaller instances of the same problem. ; Z) c+ x1 [* b J, \! s3 {; B * {# E# {% [8 ^7 |' a- G% C Solving the smallest instance directly (base case).3 Y, p8 v% q, f* q' m5 F4 ]
; P# Q3 s5 r, b% B
Combining the results of smaller instances to solve the larger problem.* X1 H; Y8 p8 I, f+ J" K. k
6 h; _, C2 J5 |Components of a Recursive Function5 d! M' p& F& d4 `/ \5 ?7 k7 r
& @6 ~8 U1 i8 Z$ U' v+ K
Base Case: / h( p! B1 P! C, u Q& `! S+ D& {
This is the simplest, smallest instance of the problem that can be solved directly without further recursion. # i% H4 e7 e( e0 U; b! K4 c+ O4 o
It acts as the stopping condition to prevent infinite recursion. + j) x4 v3 _+ l! S! K' i- w 4 ]" S" k! Q4 `) ?2 k& F' Z Example: In calculating the factorial of a number, the base case is factorial(0) = 1. ) p. C6 Y, g+ y " u# m, y9 o6 u. X4 B/ `2 \4 Q Recursive Case: ' q- T& l4 f& E# Y7 V, D1 N9 j5 e! M4 o
This is where the function calls itself with a smaller or simpler version of the problem. 9 W/ P, t) f) y4 F2 p7 l- O0 |$ p6 i# v
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).1 q" f# p8 a' ?
$ T2 F3 {- V" s9 E% v1 z
Example: Factorial Calculation! ?1 I& R9 T, D, @& E, t
+ I. s' }! H, tThe 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: 2 k2 Q* N! Y0 v" ? - G& y' W+ T7 O: R5 k Base case: 0! = 1" ^3 E% m# `0 K7 W
9 a Q4 {* {6 T2 x" v/ p3 v" o Recursive case: n! = n * (n-1)! - j6 {8 X$ d/ C+ G0 N5 i& o ; M K" C- f6 Y! [Here’s how it looks in code (Python): , Q. o; ?3 V2 p1 Ppython+ f; ]# R/ b7 n4 L
/ u9 ~$ D9 ~: a( J2 V5 L" J
7 e! p; |% S v5 [6 o. d, v3 w
def factorial(n):3 x" G% t+ y/ f+ R$ x ]
# Base case % R. H) T+ u4 Y4 p5 {/ r! d if n == 0:$ \, m4 \+ ^8 J- l
return 1 5 T; F% W" ]- ] D # Recursive case ( L9 x% f+ P. \ else:9 r+ {* g$ v* E1 f7 _
return n * factorial(n - 1), r9 |) {) K# S1 L) ]
+ }' W% u J2 F3 w( v
# Example usage1 Y2 r! E& p: Y5 v; O. W
print(factorial(5)) # Output: 120- y7 o9 w5 l1 j- R# s, E3 v
9 k) U: _5 h6 _7 \
How Recursion Works 2 t* h. S0 l8 H8 X0 w: f7 J6 |0 _: A* ^6 H8 }/ x6 b7 o
The function keeps calling itself with smaller inputs until it reaches the base case. , K% e7 j6 a4 i 9 Z& u" H& ]6 t% E1 ?4 Q* ^- K Once the base case is reached, the function starts returning values back up the call stack.( R6 a% P1 p$ n$ h" L
: X& z2 S9 A- n3 k1 R; W These returned values are combined to produce the final result.: I' m# h5 H' m" R3 Y
3 t6 U2 B9 v1 B& Q5 m, J! {Then, the results are combined: : H! d) X" }" d5 ]6 b: \) w+ T! a / Q6 t% t' l& c S" z1 D* b 5 J$ g& g2 C( l3 F- B3 I3 pfactorial(1) = 1 * 1 = 1+ a( n9 c1 U8 B ~# I( R
factorial(2) = 2 * 1 = 2/ J, _% x1 h% q! n+ z4 \! I; a
factorial(3) = 3 * 2 = 66 D' \* T# W& Q( c. a/ o* P# ?
factorial(4) = 4 * 6 = 24 3 e% U, T( Q2 ]1 |" f! k1 @% i tfactorial(5) = 5 * 24 = 120# z; A" w7 b) s& V. @6 g) c
0 }) B% `5 D2 M; [) `
Advantages of Recursion( P0 e: X" b n) K! B+ h( C* f
) L/ A- K. A" }0 @4 \4 y; ?1 y0 s 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).. c( G0 v' M" i
: ^% K% Z, V2 B Readability: Recursive code can be more readable and concise compared to iterative solutions./ D+ E; Q, @4 }* o. `9 b
) w9 r: A' O$ Q
Disadvantages of Recursion ! Z4 C) w' k( T7 p$ J2 y/ v4 z: Y4 g( _9 i5 Z3 w
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.5 u2 P; a# _4 @+ s/ B
( A9 k# B! p* ~5 x8 R( c Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). : O$ G) X/ y A0 m* k" o2 Y 9 J7 f' H+ ]0 aWhen to Use Recursion 7 I: A/ u) [* e7 Q( |% f: A; ?# V( j# C% m! O* K
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). - O# h' d% P4 R " w0 H& `* ~5 K) Q; k0 E Problems with a clear base case and recursive case.: c3 u1 w w7 o3 P. X, a
1 x3 v. T3 m; i1 k: @1 d5 p6 n& i
Example: Fibonacci Sequence % n& ^, M- V3 y0 K( D % D0 c1 h. k+ H5 j* C7 xThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: $ _$ ?7 s1 @& k0 b& g* j: g5 v# @& E& l! @
Base case: fib(0) = 0, fib(1) = 14 B0 b! H) S5 l; ]- ~' r
. q, j8 s& F) l4 t% E1 T/ q+ X% q5 Y Recursive case: fib(n) = fib(n-1) + fib(n-2) " F& c# R6 y1 [ % H) t4 x4 W" N& o: J) S! h# x$ apython & i6 h1 \7 d6 o2 S/ E9 G3 {+ h 9 t$ K8 _' H7 S: a7 y0 x0 ~; \' `+ { k/ ]; T/ i% b
def fibonacci(n): ' i/ }% _9 h8 H" w0 I5 p+ R; O # Base cases 2 J& Q) B$ J4 c7 c2 _/ q if n == 0: : j$ O& W: g: _ return 0 8 L/ ]+ n9 @* f g5 V elif n == 1: % ~/ Z# s) q- y/ |8 a! | return 19 h$ O# O Q$ V4 a1 @/ p
# Recursive case% M r; Z( A/ ]$ ?
else:+ `- h. Z" b7 j
return fibonacci(n - 1) + fibonacci(n - 2) 3 z: j% q9 d8 G; w5 a / v/ [7 `: @) d; R y# Example usage $ `+ o; C4 J' v. g/ x* F" a4 pprint(fibonacci(6)) # Output: 8 8 |3 O% e" g) h4 S" x % k: {& w0 P J+ h4 R( d2 ]Tail Recursion" H' B8 r& a* q9 a" g B
0 ^/ k9 u% j, n; m/ O# \& m
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).$ ]; E9 m N, J9 p1 Z
7 c9 _5 O+ P, J( D0 K1 ]
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 现在的开发流程,让一个老同志复习复习,快忘光了。