, [ F5 {7 ~, ~. t1 \& \' p解释的不错" _$ `7 F- g( E8 v% Z3 V5 X7 u
7 x7 d& f. U, Z3 U3 R8 U. ~) l
递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 - H* s, N, v' V ' @. [0 i7 y' x% F9 L* C 关键要素0 ^) S# g+ J$ ~5 d* j7 U5 r
1. **基线条件(Base Case)** 6 {- r1 [( y+ m. |+ j; H! \- t3 V; V - 递归终止的条件,防止无限循环 S# X9 x! M& c: _ - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 1 I( g7 A# `2 f$ a- ?) @$ I7 \* \6 d, T" r
2. **递归条件(Recursive Case)**$ J: w) P3 W" J3 b) C
- 将原问题分解为更小的子问题 8 l' h) _; @/ W4 ?6 X - 例如:n! = n × (n-1)! % l* i) }* i5 s- K: R9 ?( h9 @6 s W
经典示例:计算阶乘 ! T# y9 ~$ l. epython8 @4 ~! n$ F9 v5 n: D$ w
def factorial(n):5 `8 D3 I+ K( J4 h0 a- ~
if n == 0: # 基线条件 ) o, p/ t( J7 G1 F# R return 1 - w3 g& b+ W" B0 @0 L+ W, S6 g7 [4 D else: # 递归条件 ' l: i! R3 {1 j) b; S* a A: Y return n * factorial(n-1) 4 N) L0 b4 R8 j执行过程(以计算 3! 为例): 9 a% A, f2 \& v: Z# ^: jfactorial(3)9 W: O1 H% y, }" K
3 * factorial(2)6 f" [) T8 x) a0 s; ?4 T- K0 u% f9 K- Q
3 * (2 * factorial(1)) / z% t/ [& Y: \3 * (2 * (1 * factorial(0))) % l, u! E5 v5 ]. O g, \( g/ R4 u3 * (2 * (1 * 1)) = 6 $ h) z- x+ n- p5 I% |/ F+ s; H/ t+ z& E! U. [' s) _$ [" u
递归思维要点: C" W _ i+ L6 H3 ]4 D
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 : a$ t9 Y) X$ B, y" M& R U" Z2. **栈结构**:每次调用都会创建新的栈帧(内存空间)+ `: U. C2 b7 `* p: L
3. **递推过程**:不断向下分解问题(递) - B2 P$ W6 @6 I u/ ?$ n# r4. **回溯过程**:组合子问题结果返回(归)$ L( x' j% f4 G
7 S$ B2 i3 Q) Q5 J0 `9 h; ?
注意事项 % G% T7 G- {3 Z( I6 f8 c) x必须要有终止条件& |- U F* I. e( g2 X- [! F
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) c6 p [2 D& z( F, d# n( R. v0 f
某些问题用递归更直观(如树遍历),但效率可能不如迭代 7 {! P p4 A5 |0 Z& e5 F尾递归优化可以提升效率(但Python不支持)8 }9 [& X: a2 u7 K, ]6 ~- x
0 O3 F5 o4 _; f( R+ S 递归 vs 迭代 ( D" e" w& O, f3 d( e0 [| | 递归 | 迭代 |/ ?/ J, h) t' Q9 \$ f
|----------|-----------------------------|------------------|( R; M. U: L& \9 v4 G+ n/ g
| 实现方式 | 函数自调用 | 循环结构 |9 F5 M6 @6 t7 _. h( J. C. [( V8 j
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |. C' I$ f( y5 Q* y9 b, t( Q: o
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |* P Y# Y9 w* K& k+ w E" ^
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |8 s; n% E G2 K8 }4 G0 O
0 ^0 U' u* }9 I7 x7 t 经典递归应用场景& K4 `* ] P: t; b
1. 文件系统遍历(目录树结构)( |6 u5 z h; i! s6 ]
2. 快速排序/归并排序算法( {% k- X. t, x: r4 S3 x5 o7 G
3. 汉诺塔问题1 l2 c7 m5 c( S/ M( |
4. 二叉树遍历(前序/中序/后序)4 [/ {, W# p3 l, C! w' e6 L+ N
5. 生成所有可能的组合(回溯算法) ( Y2 q5 @4 {$ b+ V) ^ 4 i% G9 i2 q0 N9 S: ?% V试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, 5 {, A4 U1 T' C我推理机的核心算法应该是二叉树遍历的变种。2 u' X% Z; }; O7 G h
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: - P( Q$ r9 i% Q9 i6 `$ _5 J) zKey Idea of Recursion 4 c- d# u0 a2 C; `8 F* x & G4 I2 b" E O' ]' \) ]A recursive function solves a problem by: " M2 q; I" l7 {5 ^# i7 P6 A7 ^7 c% h2 j
Breaking the problem into smaller instances of the same problem. , m7 T- v5 _3 T% u! d' K. D: z; q/ J2 {+ \' e5 v2 l
Solving the smallest instance directly (base case).9 B% s) k' p2 z6 t2 @ H1 u
# Y8 S0 m1 {6 E& a
Combining the results of smaller instances to solve the larger problem. ' b/ \* `, e) S( [! x& K; W" L7 M$ p" Y1 T7 `
Components of a Recursive Function; ]7 c/ [4 r* n9 J9 w- ~
* J8 x( i* a/ i, L6 ]
Base Case: + s8 `' m- l" S1 W! W2 a5 ~# t; `! {; ]' V) f8 H3 k
This is the simplest, smallest instance of the problem that can be solved directly without further recursion.3 c( F/ }! P7 e( b3 m
0 @/ A9 q2 Z0 T( q5 M It acts as the stopping condition to prevent infinite recursion. ! @2 [4 R( _6 C% m0 k7 w z( R8 ?5 k( H8 ]' m1 u6 ?& ]/ I
Example: In calculating the factorial of a number, the base case is factorial(0) = 1.3 P6 M1 v) ?; C9 }7 q* M) H
6 _* }0 g( c$ \: [# D+ t Recursive Case: - g" _ ~) l1 ~* T9 d0 ^+ w H1 U
This is where the function calls itself with a smaller or simpler version of the problem.7 G) {9 }: G' U% O" q
' s6 D+ o# v- b% r; ^- V Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). + K* _0 o4 B' \) f9 c" P, H5 F: |2 X" X: e" U( v
Example: Factorial Calculation. i# R E1 T; B3 K, T4 t7 M, {
( u& i; o# y) g1 V2 r
The 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:1 M) D7 r- v" y$ w& w
9 t, J' k: ?9 F) H Base case: 0! = 1 7 S" M( k* ^4 _+ B* U% Q( K# U& |" I; }3 C0 t' e$ \
Recursive case: n! = n * (n-1)! " [+ l0 P/ k4 b / [' C0 K! @7 SHere’s how it looks in code (Python):+ O3 a# M+ Y4 u/ O' v
python " j3 g6 W' @% ]% R9 Z2 G$ ~ 4 U$ b2 |) B' p4 i8 Q7 {. h2 J# x) n- z- n# z0 U
def factorial(n): / M" O4 W9 K, X% u/ ~0 {+ d, Z7 k # Base case( ]% Z" F# {9 {6 _
if n == 0: 7 L: T$ B$ h6 z: p5 Z) ? return 1 0 F; @ W# u8 X% x # Recursive case + N/ {# \9 L4 W* X% O else:0 ^7 C5 S, l' R W0 |
return n * factorial(n - 1) & U N- k3 t- s! k4 A% x! I* R / |& ] J" D! p; d9 ]" h# Example usage4 B& U3 R( n" Z g1 q. E
print(factorial(5)) # Output: 120. {! P, k8 s) A& a1 M/ w o: R+ j& P
: t; _0 j& n$ b6 U" DHow Recursion Works / Q7 z0 x- Q& k/ v) z8 t8 Z) E% x' s
The function keeps calling itself with smaller inputs until it reaches the base case. 5 z# x. @- N, V+ [ 6 ] [. E2 `1 { Once the base case is reached, the function starts returning values back up the call stack. 7 L$ x+ w) ]! b7 u/ o6 o 1 a T% s. L" L0 ^/ t1 k These returned values are combined to produce the final result. . V4 D6 U! w$ N [5 P$ H. Q# {2 Y% t$ a- z
For factorial(5): + G, O/ X; ~) b3 T( r 9 H) A6 A+ F& A" {' s4 I( e/ F" W6 \9 d7 l' B: d0 s$ W3 l
factorial(5) = 5 * factorial(4) % G8 J$ O4 C" d% ~# s: ?8 }2 `factorial(4) = 4 * factorial(3): D: k' n& H( b% a! F! ]
factorial(3) = 3 * factorial(2)6 s' I( l- Z$ ?$ n2 b0 J
factorial(2) = 2 * factorial(1) 9 K5 j% O. e, Tfactorial(1) = 1 * factorial(0) 7 c. v a+ f9 ~' W; Ifactorial(0) = 1 # Base case 5 O# t$ [" p0 d& a( e ! P: x) k- l5 ~" R) F7 qThen, the results are combined:& } z; z- C; E6 \% x
2 v. t0 H& z6 m4 _* V3 a, g8 R
# v% m; y0 t3 e6 c" Zfactorial(1) = 1 * 1 = 1 # \: G& [1 d0 r( b1 @, ?7 Afactorial(2) = 2 * 1 = 2 6 {) I/ f9 M3 K$ Y! Zfactorial(3) = 3 * 2 = 6. m# j/ T3 S; D3 I. A. b
factorial(4) = 4 * 6 = 24. u, r: [; A( B& ?
factorial(5) = 5 * 24 = 1203 ?, W' v: r0 @/ r1 i+ B
8 Z m# ^7 s6 MAdvantages of Recursion * A* p. Y2 G+ W8 [( E$ B* X8 ]) k, V( u
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). j$ C6 U; H: |! Y! u7 u4 H, T/ u& H6 o- u' n/ U
Readability: Recursive code can be more readable and concise compared to iterative solutions. ' p+ W1 q/ H! x$ [# J' u, r! k! w8 Z |
Disadvantages of Recursion * }( X: A8 r5 h4 o& }' Y( D + @" g' s( w# w6 ?+ t 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.9 w. X2 a, m; G# y& h
& v# N' |$ e8 p
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 3 j" U0 _0 h# f: F( o$ @ " ]7 }+ r: D6 e- |When to Use Recursion : }+ d6 Q: T/ ~ T( e. u 1 i/ G# i$ L8 _1 L$ k0 k8 l- R0 b( a Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).& j! s7 T. W2 s/ z0 V) Y
+ G- @8 M! u5 M9 g* i Problems with a clear base case and recursive case. Q7 b4 V! W7 d6 D3 X! P) m8 Z- W2 P1 ]: C- w) K
Example: Fibonacci Sequence " R2 Q0 H* H+ _9 `* D- i- L1 @7 p" f* T0 m: a
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: 6 Z+ U- p! G: J- h& x# J8 E% z/ Y9 q6 }
Base case: fib(0) = 0, fib(1) = 1 . f" n& c1 a+ b: D5 v; @: {+ e4 ^. L4 a
Recursive case: fib(n) = fib(n-1) + fib(n-2) 3 K) k9 \2 G- M- K3 R% l# n, U9 I& ^2 A9 j
python % i$ D) I" A8 u7 K$ h% m9 d % u, n! \; H. `0 f" a( {6 b' W* ]# [( q5 G W
def fibonacci(n): 6 g3 k8 K% x) X # Base cases 6 m5 T' e) \+ c r, F! a if n == 0: 5 u$ X c% t Y I( z7 Q8 m return 0' v8 b" e. |# k
elif n == 1:7 @7 o g" u# E7 g |6 W M; _! q# e
return 1* O+ q+ N. }. @5 N$ I! ?' h
# Recursive case2 z: I& f& ` a, j: T# M( D7 c" Y
else: 1 p" I& T/ T6 @/ H1 x' l return fibonacci(n - 1) + fibonacci(n - 2)" l4 U( h5 _5 p" e8 I) x
- j8 M4 a* C. g9 y1 u% p) U$ y1 ?
# Example usage1 u* c8 N' q& n' [ P
print(fibonacci(6)) # Output: 8 1 V4 T" ]/ g0 O. r: i0 U + S" A/ ?* I2 ~Tail Recursion 6 Y# D0 C Q$ ^! } 4 H8 d0 [ x7 D- n" ITail 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).: P8 x N! e" R9 ?3 g
( ^' ]' {3 Q6 ~3 T& N& p7 _
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 现在的开发流程,让一个老同志复习复习,快忘光了。