$ [, Y5 f- |* x; Z递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 + O0 J! w" m. Q, |9 w, G% L J: y' Q+ ~! T
关键要素1 l. o8 J. W6 M! o' X% J. F
1. **基线条件(Base Case)** 6 z9 p6 s$ m& J- i - 递归终止的条件,防止无限循环: X/ |2 J6 a+ g) O& R( v
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1( o2 ~0 Y# X0 d! O$ m/ x
1 I# z5 G/ p2 D5 V4 S2. **递归条件(Recursive Case)** - |$ I# W2 X4 J/ r. b: V8 r. t - 将原问题分解为更小的子问题8 G+ m, Q3 ]: A2 |) V% j$ K, A
- 例如:n! = n × (n-1)!7 y. W3 h7 t, h+ I
3 Z' B4 d$ K- U1 U+ { 经典示例:计算阶乘 2 ]+ \; L( }1 y4 T! Lpython$ e7 d" l& ]. ~- {( h2 u' ^/ T
def factorial(n): ; V+ w6 Q+ c2 v if n == 0: # 基线条件3 Y5 ]" S" p. e6 F$ K) r1 `$ c
return 1# k; h, j; ?. r' {# u7 M0 i
else: # 递归条件8 }3 [% U, c* M! r
return n * factorial(n-1)' a, l9 U" ?$ f T; `1 E R0 A. v5 A
执行过程(以计算 3! 为例): ! o$ E) @5 G2 H2 R$ efactorial(3) 6 N# ?/ K! V0 W" k/ i' U3 T6 G* F3 * factorial(2) 8 c4 `1 a: c( ]' ` O7 I- i# X3 * (2 * factorial(1))" _) w/ P* ^4 q" ?2 a4 o" X* x- h
3 * (2 * (1 * factorial(0))) 5 f- f' V( w5 X3 G2 X) w3 * (2 * (1 * 1)) = 6* B2 l$ T8 |- Z; ^
8 D) H- |, c. r2 |" X" l: Q4 d
递归思维要点 2 i4 k2 C0 g p: p" S4 O1. **信任递归**:假设子问题已经解决,专注当前层逻辑 # i: j/ c7 k3 ~: R2. **栈结构**:每次调用都会创建新的栈帧(内存空间) 8 w" \0 Q3 u; y6 |( o. E! p6 m3. **递推过程**:不断向下分解问题(递) D% t. s0 @' H ^4. **回溯过程**:组合子问题结果返回(归)0 U8 J$ v! i2 n
$ h& S4 |1 q/ c$ [+ U# v) _
注意事项 % ^! D) k$ H& X R& ~& s% M必须要有终止条件 + X+ |' R0 a: G5 p+ {; h2 r6 d递归深度过大可能导致栈溢出(Python默认递归深度约1000层): k* e7 M0 @2 F D0 G% p9 Z
某些问题用递归更直观(如树遍历),但效率可能不如迭代 , P" M: i8 y9 Y0 o4 ^* q9 Y3 L尾递归优化可以提升效率(但Python不支持) ) v" R- E' j+ N) A: r 1 i A3 |6 l$ i/ p1 x 递归 vs 迭代 . M# V c; T$ {% I8 ?| | 递归 | 迭代 | ! C+ M* N- }4 E3 j% J|----------|-----------------------------|------------------| & t% M/ N" S; ], I. {: H0 a( i1 g| 实现方式 | 函数自调用 | 循环结构 |& \# s) C- X9 a+ O6 `2 J
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 2 x% i, D r$ V( Y( y0 t| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |, }+ ~8 G% s: C' d
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |+ \4 l; N! {$ [0 B
9 t2 a. H: j1 w( F 经典递归应用场景 1 e# k$ c: j3 m" C1. 文件系统遍历(目录树结构)7 H+ x3 j _- J( S. ~
2. 快速排序/归并排序算法" s- l; f; v# F' ~! C* |$ S
3. 汉诺塔问题/ e7 v% Z) p1 F5 Z
4. 二叉树遍历(前序/中序/后序) ( n* Y6 ]7 N1 S5. 生成所有可能的组合(回溯算法) ; F; ~3 j, N" F5 h + [4 R! A$ G9 F0 A& T5 M试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,+ F/ V" I4 z! ?7 R2 U0 |; s" H/ D$ R! c
我推理机的核心算法应该是二叉树遍历的变种。9 X& B, D* x6 \5 T: q8 r2 l* `
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:& [3 d9 y# u7 d* a5 T
Key Idea of Recursion 0 I5 R4 b! V7 L3 s* b3 a9 y3 b, `1 U' n) W8 U! S, j& E; ]6 N* w' _
A recursive function solves a problem by: $ O3 @. d1 _+ a/ c; V% Y# e% u z6 G) P, V8 V. d* l0 I2 j Breaking the problem into smaller instances of the same problem." P5 A7 E; i* c# A3 a `
0 Q- X7 M$ x" C; k$ l) m- Z
Solving the smallest instance directly (base case).- @- C& b; s9 P% p# p; x6 I/ q/ ^
3 V$ @* C1 b: I, h) J) b. h
Combining the results of smaller instances to solve the larger problem.5 c" r4 H' ^5 ~0 h/ @
4 }, h, i8 G& _. @% L
Components of a Recursive Function, `3 f, |0 X3 U- ?
5 o" ^% U4 r: M
Base Case: 7 B9 y$ E2 \" O 0 \! j1 c$ m2 u1 H. U T K1 z This is the simplest, smallest instance of the problem that can be solved directly without further recursion.) @$ L" V: x; N, Q
" y3 n9 {0 z- q! F! T6 t$ I It acts as the stopping condition to prevent infinite recursion.+ O" h; ~% {1 O6 b9 d3 |$ d$ m
! g* p$ W- @- J
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. ' {# ]" H7 _' } 8 p' T- V( U( v: c ]0 ] Recursive Case: , x; e/ i: d `- Y* W# o% o ; L( Y4 R, k& ]* G2 F% S3 L* D% E( R This is where the function calls itself with a smaller or simpler version of the problem. - R9 R) T8 v! J0 ? 8 b' ~! d8 ]4 D, F7 G Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).4 r. j5 d! A: Z# { j
+ T# `; c# F+ q% E3 V: P e( X
Example: Factorial Calculation1 f' c% I, \. z
, I, l6 r! S! e7 bThe 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:% M$ Y2 B! Z- G5 t
& i2 b k' _+ A% L/ A Base case: 0! = 1 & i$ z, w3 `' a+ S5 i J6 H7 X5 l
Recursive case: n! = n * (n-1)!; B# O7 ^* r* q8 M4 `
9 f( H @( q' q7 S" X3 @
Here’s how it looks in code (Python):, ^6 L" Z5 n; Q$ V3 j% Y
python- j- o4 F7 B4 u. x- M
Q4 d1 O- Q; g! A. s
( W* t j# ~ Q9 [4 a5 }
def factorial(n):( ^; z9 A$ ?3 i1 W/ X1 l
# Base case 2 E3 p6 i4 K1 A' \& n" A+ P% D if n == 0:6 |1 C# V- W7 o" f! p f) f
return 1 2 i5 i9 G* z3 ^7 w" H A' X # Recursive case: m. u/ X, t; i' {. e/ R9 N
else: . {' d. T7 h ^6 D: ]+ y3 A# N return n * factorial(n - 1)) S0 V' R' y7 ]% k
) I) T7 I) D7 A3 u7 }& u
# Example usage 1 ?6 Y+ b: \0 m- a) d1 Mprint(factorial(5)) # Output: 120 3 ^7 C! {' v# v% m: o9 V ! D; b. T" ~/ m0 l8 ~How Recursion Works" W g8 Q. d- A
. B5 \; ]& ]; O. W. @
The function keeps calling itself with smaller inputs until it reaches the base case.+ M8 r! m( A$ D5 c; K
4 x& H- n- U# X$ s$ G: m1 {) c
Once the base case is reached, the function starts returning values back up the call stack. ; m1 f, I8 G$ e* `; U: s) b, h% u( z
These returned values are combined to produce the final result.- ?2 U! h6 y* N- {
% @$ d1 \, O: z7 d x
For factorial(5):. C2 r' o1 P {+ \2 ?
# l* p* ?7 p$ J! E4 M0 d& w9 BThen, the results are combined: ( C' m) \7 A% O0 z8 e! U2 k* k% A G7 t$ q) W# G& b y7 ^, Q
# K/ C. ~8 u f( l4 A
factorial(1) = 1 * 1 = 12 ]& s. y2 Q p
factorial(2) = 2 * 1 = 2 ; f" f5 G! K. x2 {factorial(3) = 3 * 2 = 6 S Q/ Z$ a7 U8 r2 S3 Q- wfactorial(4) = 4 * 6 = 24 1 _) G0 y5 n4 X; zfactorial(5) = 5 * 24 = 120 / }; @8 o( ^5 r& J0 t- h" Y4 ]" f ! C/ `& k6 |; [Advantages of Recursion - v7 i7 f5 d9 y6 i, ~$ E 9 S$ q' H* j! f3 d 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).% ^4 S# U1 k+ | l b* t9 }
6 v0 x! H5 z4 U" E& F Readability: Recursive code can be more readable and concise compared to iterative solutions.( Z/ f0 |; W. a* o% P
/ W" g1 V9 n _Disadvantages of Recursion ) K5 b4 {# o: V! y8 p5 z- A& L6 Z
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./ Z* `% I5 V$ t8 G& t( m+ [
7 \7 x# u# e0 i0 m Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).+ o! m' b: l+ j. c+ K
0 q) x2 c2 g) l/ X( T, X8 S
When to Use Recursion . f6 x+ ~' L# M1 O% T l7 l5 C; i3 w
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).$ m. V+ P$ {: T6 q) Q* \1 \+ W* A8 n7 U
8 U! R0 @! w6 k9 Q) H1 k2 e! {4 e2 f
Problems with a clear base case and recursive case. 4 f L% Z1 [" C* W) x6 p- i2 g; W+ D m5 C9 ]
Example: Fibonacci Sequence$ W; C: X/ \/ A9 y( I+ s& ^
& a* @9 \0 E) [# H# i% I" s
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: 9 q% J, v( h- t+ x9 z7 |: b6 O: j+ X. A3 l6 T2 c
Base case: fib(0) = 0, fib(1) = 14 v7 N; P6 @: H
" r1 O) r4 r9 [/ P+ l8 X4 i; y
Recursive case: fib(n) = fib(n-1) + fib(n-2)# u0 ^; z3 X1 N4 p5 D g e- L. }: n
! @$ @* v. J& y) E7 s* y$ ?4 c0 C0 s" Dpython' Z. e4 d( O+ w8 Z; M) u7 U( `
2 h, j3 W) y8 u* }7 s$ u8 ]0 t
* S7 J% a. m$ W5 ]7 M
def fibonacci(n):% q6 o: W c9 h% Z" G2 |
# Base cases 3 z Z0 V5 g" c" y9 M if n == 0: % d' m: d2 \# c& ~: k$ r return 0( f+ q' K$ g# v: t( }( X# s
elif n == 1: ' ]$ d7 Z; a' b6 } return 13 J& ?/ v4 p. Y* }2 Y, h
# Recursive case 4 m) Z1 V% x8 ^ ]6 C else:" J8 Q2 |0 p0 R2 I9 H7 A. d0 I
return fibonacci(n - 1) + fibonacci(n - 2) ( q4 L! {# J$ r 0 v+ S9 D; ]* ~ U: {. s# Example usage 8 {0 t: ]" h" ?' f4 ^- R. a. Wprint(fibonacci(6)) # Output: 8 + v. h: U! d+ U1 u# I+ L! Z6 B# ~1 b: E+ V1 X$ p3 P
Tail Recursion3 N( \9 ]3 F) Z3 q
$ H. `7 r! k9 r" 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).% `% [( N# G$ K7 M
& N3 u3 D5 H' C* L8 P" HIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。