' u3 P) ?7 y+ Z6 |# [解释的不错 & G9 ~4 I3 L5 P }) ~! k. | 6 T. R& _; @0 h# |* L6 [& r递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 $ E% B6 X- G D# ^2 B/ }5 @, w2 n! G. g: X# _- o& _
关键要素, `8 G! J2 b3 s% K5 f4 \
1. **基线条件(Base Case)** % I0 T0 [! _3 A% \( }3 i& b - 递归终止的条件,防止无限循环. J9 R& z8 ]7 z4 F/ H. r, p
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 - e- Y# M. z' ~+ z' b( M& A % I- i, Q- g6 w6 B' z8 @2. **递归条件(Recursive Case)** " P1 ]. j7 ?8 e - 将原问题分解为更小的子问题 3 G9 g. ]' s |1 U+ A S - 例如:n! = n × (n-1)! 7 P" |1 ]- c" N 3 _; \3 \9 I; U: ?9 f1 x 经典示例:计算阶乘 . [/ U6 @& O5 S. Upython. t2 B. d6 F6 A2 v/ t
def factorial(n): # P6 B, a6 h) y if n == 0: # 基线条件 4 L' G( j) I( h- W# u z return 1 - Y3 x0 `. W8 x else: # 递归条件 % g; H% l; m; q5 z; M return n * factorial(n-1), F6 \6 E9 |% ?( {) H2 F
执行过程(以计算 3! 为例): * h) S* d0 v ~, i0 g* j' afactorial(3) t+ O s4 u: r& D3 * factorial(2) : v& V& f) v) \1 V6 V3 * (2 * factorial(1))0 s6 F* ~2 M/ F0 s
3 * (2 * (1 * factorial(0))) 9 ]) R W- L2 S4 q3 * (2 * (1 * 1)) = 6. U3 O4 h: v9 t9 p5 e
5 O6 W3 |4 Z; N+ x+ Z0 P: v 递归思维要点 . r% \8 l9 J! I2 X7 W! U2 s' f1. **信任递归**:假设子问题已经解决,专注当前层逻辑2 ]% h# t* D# l$ U5 [$ I
2. **栈结构**:每次调用都会创建新的栈帧(内存空间)0 \, K9 a& ?& R# r
3. **递推过程**:不断向下分解问题(递)( J$ c! E1 Z" u7 V' }
4. **回溯过程**:组合子问题结果返回(归)6 p& ^! ]6 D- ^$ d* o" N/ Z1 B0 g
$ ~0 j3 o) Z# q+ ^
注意事项 8 C I& \% O+ Y" b必须要有终止条件 ! h/ f- C9 P9 j递归深度过大可能导致栈溢出(Python默认递归深度约1000层)5 v0 m* S) R% L" g6 b; X% X( A
某些问题用递归更直观(如树遍历),但效率可能不如迭代% e' y# y' R$ e' y: U+ O$ g" A4 J) P
尾递归优化可以提升效率(但Python不支持) % O3 ~0 |3 O" F7 S) b s( o & ~; f( b) F6 E$ p 递归 vs 迭代 1 w6 l- s- I0 f; @5 ~0 {# `| | 递归 | 迭代 | + D" ?* N9 J" ^% R8 m5 _|----------|-----------------------------|------------------| # |: z* N4 j) s& b$ i: L4 K| 实现方式 | 函数自调用 | 循环结构 |/ |' P! l$ J% G7 G- B/ ~
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | ! x/ Q8 i2 y' y% R$ d5 @* }$ ?# F| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | . I* w# e" J' j& y6 _| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | l/ j" w# Z; r: G
' a8 y: {0 x+ w- f
经典递归应用场景1 L, q! Q& [2 J* y
1. 文件系统遍历(目录树结构)' `9 z8 g/ F1 H% ^2 C/ a! m0 R% n4 Z
2. 快速排序/归并排序算法 9 k5 d. b1 V, Z8 E$ k0 v4 ?3. 汉诺塔问题/ Y7 _8 z: k1 w7 A' [
4. 二叉树遍历(前序/中序/后序), V" N: Z; r% P; ]
5. 生成所有可能的组合(回溯算法) . a5 L9 ]% A. P; d* }9 c ; M& G% P7 {5 @" g试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,: {; V/ [7 K% s4 m# Y8 y" i
我推理机的核心算法应该是二叉树遍历的变种。 4 `, d6 Q K. i k( b/ e/ o另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: # J8 q% V* t: s) ?8 s* jKey Idea of Recursion1 `- D4 U/ \+ O9 J' Y
. F1 U' e3 [0 N; Z% m: UA recursive function solves a problem by: ) n9 L* ^; [# _8 t8 U/ [& a- \ z2 c8 V) C, y, x
Breaking the problem into smaller instances of the same problem.5 y# \* I4 ^. U2 L7 x; C% M0 U
2 b' V& k7 F3 P& D6 D3 o Solving the smallest instance directly (base case). , e M- o8 U- _9 V/ \ : c1 G4 v" z0 T" N8 j: ` Combining the results of smaller instances to solve the larger problem. 4 n4 @& J K( Q" G( v7 Y8 p7 E2 d3 Y( x9 ]! f
Components of a Recursive Function( \+ }( F: I$ p( l" ]7 l/ t* a3 b
4 ^% {6 j, n* p6 P; w2 U% c Base Case:' N8 N& K7 O @* |; }# |0 R3 P1 Z# |
, [# X% |: Z: j: A
This is the simplest, smallest instance of the problem that can be solved directly without further recursion., T& Q4 [: z* O& y$ D
6 }/ C: Q3 K, w* w It acts as the stopping condition to prevent infinite recursion.. U* m" X) C8 u( l
' Y4 P% L- A8 S
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. * l& N& Z# F3 R3 E- N 5 z, v9 T5 T0 F3 E* u* q7 i Recursive Case: " M- v5 m' I0 P 3 F' W* Z) u9 {) d) N0 @ This is where the function calls itself with a smaller or simpler version of the problem.6 `$ r& L0 }* I5 J3 ]6 |7 x' j
% Y8 S8 Y6 |2 S# \/ |5 i
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). J3 ~) ~! I5 Z0 R: ~, O# z: U0 ^3 n" a- O! a5 ~0 O
Example: Factorial Calculation3 ?) F( O5 @* K9 g; G8 K
* a7 v P. v, m' ?7 aThe 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: " a1 f( i' ]: D" K 9 ?! c' x5 @# l' n0 r% A; ? Base case: 0! = 1 . B" F1 L% L! m. }% P ' a8 f& |+ J$ V! z& ?* R! W. q Recursive case: n! = n * (n-1)! 4 o7 o- h7 c' L, Z( E7 V8 H) Q7 U1 T T. m2 Z4 k$ s( K$ ~7 Q
Here’s how it looks in code (Python):4 i# J" m8 \& ~6 j; N0 U& Q4 E" _
python6 h/ ^' e5 S+ U% y9 V% }8 @5 m0 j0 F
, s/ A% z* u$ m4 t e+ h% `
5 u9 |) D0 ]* Udef factorial(n): 2 K" {$ [4 J, D3 ~ # Base case " Z+ e( L9 R" u$ d6 ^- y if n == 0:" ^% J. N9 Y0 }& H+ n1 c
return 1 7 i6 p* ?4 W6 o$ U9 r # Recursive case! Q& V H" w( ?# T* y' _4 K+ {
else:4 B( l7 a5 t- {- c4 u1 T9 X
return n * factorial(n - 1), M( a6 s, t5 @5 x8 q& k% Z
$ O% t! e1 m: `2 {+ W7 A! z9 v
# Example usage & O, l! h: w! r: t2 b @ g" gprint(factorial(5)) # Output: 120" M( {% c8 `; ?3 E9 u
% \! w+ n6 w' s3 iHow Recursion Works 9 \5 W6 e3 N% S- A& ]7 _) G4 m3 ~- S) \7 t) C
The function keeps calling itself with smaller inputs until it reaches the base case./ P- ]# r! p2 F+ c+ d: \ x0 W
+ \- Z3 J( z8 Z
Once the base case is reached, the function starts returning values back up the call stack.# F3 }6 v7 K8 J, U- K3 A# Y# J
- e* ]& J4 _ E* c6 q, x- W3 ~$ T
These returned values are combined to produce the final result.9 W$ c0 o" ], A$ I) j; q% n
' V: `1 B8 V Y( ~* x6 \7 i
For factorial(5): * h2 h' B: r" B7 {2 x , X) j! ~6 d& p3 b+ L* i! D, T6 ?6 N: T
factorial(5) = 5 * factorial(4)1 R, h* C6 T, m3 g; F
factorial(4) = 4 * factorial(3) " F. F+ A+ l( p# D& Vfactorial(3) = 3 * factorial(2)$ V( E0 G* l7 m7 i9 ]
factorial(2) = 2 * factorial(1)* j- n m1 O. c* Y
factorial(1) = 1 * factorial(0)2 S5 i H/ R, y @5 D
factorial(0) = 1 # Base case 4 {8 f! z0 U% ` , h: v9 X# R5 D/ OThen, the results are combined: % u% N+ d8 `' O 8 j1 b0 A2 @* W5 V% D% j1 d/ \5 n . n, O4 L6 y( k+ n* D* O" P% Sfactorial(1) = 1 * 1 = 1 % q# u$ Z( K) C, q. \factorial(2) = 2 * 1 = 2 ) _: q& `; H& X, c0 }5 ]factorial(3) = 3 * 2 = 6 % i/ c" E1 n2 j& h4 J7 @0 `factorial(4) = 4 * 6 = 24: g2 t* q' z% Q. Z- n( p! J% _
factorial(5) = 5 * 24 = 120 7 V, h* G9 v X& H" N# c : k. U% c, q& v" @Advantages of Recursion # X! m: e+ x: R; F3 Y0 q) B7 i0 w4 A: J- l! L: }1 R h
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).2 I" ~ K) s2 L, h& G3 W* \& }
& y: J- x( [, @# o: |0 T5 L Readability: Recursive code can be more readable and concise compared to iterative solutions. . r; U! c( Y |. x) E% s; K0 V6 t4 f; b, M( T2 r' e; [2 ^$ j
Disadvantages of Recursion% O$ ~6 k$ T' z) V7 } @
0 L" a( V9 u0 r" W2 h/ b 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.! y1 v& q$ W, N) _( o! A
, `$ Y& X# `& B- a
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 8 s, V0 l2 h5 r5 ^ 4 G! m3 P6 x+ z8 t" t4 F1 M9 kWhen to Use Recursion$ [$ A3 B ]$ R1 R6 g! V% V
7 y* P. k8 m8 Q4 }. _ Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). 8 Q; x* c5 _8 p/ h$ R: H3 v 0 c) N: s' E3 L+ ]# c! \7 x. |4 D Problems with a clear base case and recursive case.7 q+ z; p1 z( p! g
0 F0 j7 W) O/ l+ G8 e2 v) ~Example: Fibonacci Sequence % b: l2 r" Z% S8 @+ b4 F( d" a6 [ 2 K& I7 W! w+ n" O* F1 rThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:8 f9 {& E8 X% s& U4 r( t& P
+ `$ p; [, P ~/ i" R8 L7 p3 t8 p' t
Base case: fib(0) = 0, fib(1) = 1 5 H/ O1 _ S, X1 }6 h: q5 q( ]- u2 @9 Z: N
Recursive case: fib(n) = fib(n-1) + fib(n-2) 1 d$ [4 l4 T J% y8 u2 n) {, f # Z* ?3 {% ~6 J: Z* _3 gpython: T) y: J9 ^7 M1 G
5 l3 E1 h1 @( |1 u, X9 [5 U, R; S3 I4 E6 o: }
def fibonacci(n):7 W0 W/ V6 @3 F- z/ B+ n) }0 ]6 }: n
# Base cases ! m9 \4 o1 b' X" C$ Y if n == 0:+ r7 M9 S$ I5 o* `) _8 P; n( t- O
return 0 ; |' U* {0 X! ^1 y% h7 b elif n == 1: 1 Q& `6 U! Q" B3 M/ D1 y" m' a return 1 2 z" L0 }4 m2 X* v* w3 U, ]. K+ ? # Recursive case $ {3 b1 f6 `& l5 F7 h else:* E# [1 P- E: k9 f$ h
return fibonacci(n - 1) + fibonacci(n - 2) . d& n& M) |/ L3 h ! L# d8 I" H1 G# Example usage+ U; ~8 z" i* I' A
print(fibonacci(6)) # Output: 87 B# j3 C2 M* e) x1 a9 h2 ` p! y0 \
( [: t% _+ d# j4 M b8 E, D& ^; ~Tail Recursion ! D' ]5 _! J9 G0 h , s% u) {% `; ?& eTail 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). # Z) {8 n6 f3 c/ A2 v # j: Y6 d; B" ]! \/ n8 k! d. p: ^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 现在的开发流程,让一个老同志复习复习,快忘光了。