) w$ v5 F* @7 J/ C o5 l7 g! S$ {: F解释的不错 ( R+ J( Y3 H: `- ~0 G, v3 |2 Q& S8 W2 t- Y/ }# g
递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 ; u. ?% F8 i" R& P* h& R" U( Z4 \/ G/ e9 j" l
关键要素" |2 O' |1 m+ I. [2 {
1. **基线条件(Base Case)** , }! t4 D2 F/ W) r - 递归终止的条件,防止无限循环4 d t: M8 O @
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 3 A& ^7 a* @" `9 z2 A3 u3 R, ` w b, W& s
2. **递归条件(Recursive Case)**3 v3 i/ I5 A* H; q& |1 V$ t7 V
- 将原问题分解为更小的子问题% n N* y; s Q
- 例如:n! = n × (n-1)!& T; r8 ~+ B; M' n
/ r3 l" ]0 L! h4 i5 g+ ~9 U, H 经典示例:计算阶乘 ) @6 d7 T; p% xpython 4 x+ g5 T4 c) M/ e/ X* Gdef factorial(n): . n0 j, {2 @0 c: J9 a: q0 c& u! H1 q if n == 0: # 基线条件 7 B5 h" p" c+ F: C) {5 \* U6 O( L# K return 1! ~- n# [" j1 [$ U
else: # 递归条件 2 C* l V) F5 _ return n * factorial(n-1) 8 ]6 Z. {' ?( v. w6 l. p, S; l执行过程(以计算 3! 为例): * O0 S) X7 o0 D3 H1 `; Wfactorial(3) 4 W; w& S7 S+ i8 u8 p& Y# Q( p% x3 * factorial(2) " _! v Z3 g6 m. b3 * (2 * factorial(1)) p; z6 m9 ^) j) l% U
3 * (2 * (1 * factorial(0))) / J0 x7 b# z' S8 O. Y3 * (2 * (1 * 1)) = 67 x1 b% J- S" _7 t4 o/ J
* h3 I: r P# ^ C. \% k P# `* t 递归思维要点 1 b' O' P3 }7 `% J0 Q U0 r4 Y1. **信任递归**:假设子问题已经解决,专注当前层逻辑& j) N( x* H) |& q
2. **栈结构**:每次调用都会创建新的栈帧(内存空间)2 [! ?8 K8 y9 x- Z
3. **递推过程**:不断向下分解问题(递)4 I" @6 [' X0 b! Z0 Q: P! R, A+ f
4. **回溯过程**:组合子问题结果返回(归) # x8 w! E( h0 U; b# P6 s& G, W. T8 h, E3 j8 U8 J
注意事项 ( i! L& j) R7 j W2 g: j0 g/ x必须要有终止条件 6 S9 w Z1 [% T4 }6 K递归深度过大可能导致栈溢出(Python默认递归深度约1000层): ^( W0 W$ z# q9 U
某些问题用递归更直观(如树遍历),但效率可能不如迭代 ; k3 Q) F% c5 n7 v& r Q尾递归优化可以提升效率(但Python不支持), x% i8 l8 B9 D @; [
# L S" ^$ Y* B. s' B' z/ K% A
递归 vs 迭代 7 @( m- T& s5 U6 X# Z: z9 L5 g| | 递归 | 迭代 |* I& G5 e0 v8 w, ?, R
|----------|-----------------------------|------------------|( r M# D) ~& ^5 k
| 实现方式 | 函数自调用 | 循环结构 | ) m4 |, z$ q0 A9 |3 b| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | $ x& C: C% n, y6 K| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | : T# T8 u3 x; j) |$ [4 P| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |; ]3 a# Q7 Y9 o* ~
% p2 N2 b6 n3 S" ]# p/ k
经典递归应用场景 6 |' u9 x! \! S7 ^1 \1. 文件系统遍历(目录树结构) " t. ]& }# I! \' m7 `& {: s2. 快速排序/归并排序算法 3 b; @8 W$ Q. w! @3. 汉诺塔问题 * [; x0 O9 a8 s0 D6 p4. 二叉树遍历(前序/中序/后序) / ^2 b% d+ R& P) E" O( \9 Y3 p5. 生成所有可能的组合(回溯算法) 3 r& r* A1 [: u( P! L' S9 L 7 M3 f0 z; E/ y |试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,8 g6 N- n4 f. g2 A( T" I8 K! J
我推理机的核心算法应该是二叉树遍历的变种。" d5 [3 E) [4 a. S- H, H8 z Z& 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: & `0 s* ]9 E- v! L( iKey Idea of Recursion $ v& k8 @! L5 r7 |" j& S + S8 i! q6 j7 |. \* c- H" d: OA recursive function solves a problem by:( E' F) \' E6 z
( c1 b" }* o- T' Q3 Q
Breaking the problem into smaller instances of the same problem./ T4 y( Q/ [$ K# C2 z+ B
6 E' |0 G" Q, a2 D1 v W Solving the smallest instance directly (base case). " u* n. V* \# c7 r. O2 }8 h7 ~! P( M
Combining the results of smaller instances to solve the larger problem. " M* S8 V# G0 E e+ J5 b) f; ~" H4 R7 Y9 H1 {; a, m
Components of a Recursive Function C9 _% f+ Q2 }1 ?# v
8 t8 g( t/ G7 ^3 p
Base Case:+ c2 a; g( n ^4 y- q& B
/ G! U- `9 r n+ i- U9 ] R# J+ c
This is the simplest, smallest instance of the problem that can be solved directly without further recursion.! v# a- m( f% k& o B
" X& r; B4 [' f( W4 z% {
It acts as the stopping condition to prevent infinite recursion. ~6 K0 ^3 X) b5 I* N* _ Q
8 Q R9 M6 [- s: g5 p4 @' ? Example: In calculating the factorial of a number, the base case is factorial(0) = 1. ' Z' y' S3 J l! b% ?( s y0 u* t1 {% u" O: G% B Recursive Case: - Q9 S; O: V3 u! o$ Z: S' f ( c3 Y) n5 k2 U2 m7 k This is where the function calls itself with a smaller or simpler version of the problem. 3 A( |2 S; X. |) ?7 V/ w% |/ O( p0 \4 ~3 e0 J. u' \) i
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). + m! d. G( P/ `, n" u( P* n' z) l9 P5 U# D
Example: Factorial Calculation $ t2 h% T! U! u5 x& Q6 K- G& U% o q# c+ Y, |# L
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: i7 ?3 B9 @4 o6 Z. s
' M4 L) s) b1 R2 I+ s3 v* E( V Base case: 0! = 1 - e4 r5 O" w' d- C 4 @7 V5 q/ \/ r4 u Recursive case: n! = n * (n-1)! : F0 R4 _7 `" m8 B: U1 G3 k7 p1 B6 ]4 V& [8 ^; g6 }7 k5 F% @2 X/ c7 F. @
Here’s how it looks in code (Python):$ i m2 V7 ^+ I$ p
python * y( q R+ L6 b 7 p: X3 U s- D7 _% b& Z% H: Z1 ?, z" n: }8 ]
def factorial(n): * p$ ~5 @# F& \% } # Base case! [. J2 a4 {) B6 p* _
if n == 0: ; n( q3 J% W" \- B$ O# ] return 1 # H" |3 ^5 x0 w z* z5 n( M # Recursive case 6 I2 W2 `0 ?& a1 b, i* ^ else: - U' a- t- g, X: F( X( Q( u return n * factorial(n - 1) 3 \: q/ h- g4 ^ 1 A, [! Y% v5 b# Example usage 6 \, T5 }+ ] B x S7 q* s1 R$ Q- bprint(factorial(5)) # Output: 120% s X2 ^! F* u' H, A% P8 Y- h0 ?5 J
U( H) N. X, b9 z* C4 b) D+ ^
How Recursion Works0 r4 v& C% k- o# a
' f7 y! i& R- N) A The function keeps calling itself with smaller inputs until it reaches the base case. ' F! p/ B8 O6 m9 K1 C, ~# |; h, N! D+ A8 F
Once the base case is reached, the function starts returning values back up the call stack. ) l$ z A$ s: ~# u/ ` p0 V, u1 B& s6 W0 e+ w- U* @+ ^ These returned values are combined to produce the final result.) a9 y0 v/ k! N- z0 P: [
6 f2 I6 J( ^4 pFor factorial(5):# O4 z* L- t1 s# f& h: M& ?
2 o( [/ L! a$ m. E
0 G# v, C5 d1 v( m; Q2 `$ \
factorial(5) = 5 * factorial(4)$ i' c9 D; x. `6 `
factorial(4) = 4 * factorial(3)& w, U4 M4 ~$ c$ T
factorial(3) = 3 * factorial(2) Q: Z' g$ f2 [+ y3 w, w( B
factorial(2) = 2 * factorial(1)2 I% f, n. O8 Y# A- `0 M) B t
factorial(1) = 1 * factorial(0)# t, D0 S# ^# \7 v
factorial(0) = 1 # Base case: o" H5 A. R5 H6 s* ^/ q
% j: K8 U; t) W8 X5 J- J
Then, the results are combined: 5 ~. Q; G, J: d s. p5 h, ]" \. g% `$ L2 Z7 k
! z+ |) ]: S, C+ d
factorial(1) = 1 * 1 = 12 @( d! Z$ |6 h0 B; \9 q% t5 w
factorial(2) = 2 * 1 = 2 " R) C! B8 a# A) Mfactorial(3) = 3 * 2 = 6 ! [' |& ~/ x2 E( A/ u1 p( Efactorial(4) = 4 * 6 = 24 ' x, f3 M- X" B* k+ m$ ?- b- ufactorial(5) = 5 * 24 = 120 : |2 {5 R8 j7 V5 j- Y% k3 j2 | ; d, Q p. @1 I( n J& V0 KAdvantages of Recursion: e. v+ G8 k# z8 ~2 a# a
2 \1 v/ v1 C; V6 T/ s9 _ 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).; ?* z7 A$ [+ J$ O- z/ A
, L& I ], r1 ~" E! d0 K Readability: Recursive code can be more readable and concise compared to iterative solutions. # t9 t$ z: a9 b$ v 4 ?' q3 W: ] H {" I2 b( O; O; dDisadvantages of Recursion) j+ A, t3 c) a& V( T) S
+ X7 v7 @ Q) r4 ~ 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. 8 Y: k& A9 b6 r2 D" D" {# W( r0 D9 ~! J
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). : z) e- B" a$ |3 h. \: P- A7 d, S' X9 b3 F+ c
When to Use Recursion : X4 K: v8 N# R9 O4 g 4 w. a9 P: {' r& q3 E5 M4 F4 \& S4 D Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).8 n/ x, r- \/ c
. k7 w" z X+ X' d2 @- ?7 L- T
Problems with a clear base case and recursive case.: S9 E3 |# V9 D6 j7 X8 I
" u; p0 G, e9 n2 [( qExample: Fibonacci Sequence2 w @9 u% Y5 I; ] M2 E
7 O ^, \( }! U2 {The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:9 g& t) H; W! K% F% [. `' E4 H
1 `% L, G( ?* e- t) ` Base case: fib(0) = 0, fib(1) = 1 ( A7 M7 j, D/ ^7 s * O* z* Y$ D8 x, Z5 I Recursive case: fib(n) = fib(n-1) + fib(n-2)* d# q6 Q3 P; U2 b! v7 B$ H
9 o" S+ n9 I* X4 z/ O6 ~' A* ^python & I/ Q% v/ N$ b# a5 o6 {$ `) x' |- a& j; u: t2 x6 m
0 |! t6 s& s1 a, y5 v0 J. |
def fibonacci(n): , o7 r% E" l6 B, c+ t # Base cases7 p& a7 n- R% h) [0 x1 y3 y
if n == 0: 1 Z5 q+ ^! E$ \ return 0 4 y8 l. {& U! V+ k elif n == 1:; ^# {5 O9 W5 j2 ?# L' p$ B- O
return 1 ; r! `6 k* d# |7 o- S( j: [! z # Recursive case$ c% y5 T- V% v$ S$ w" o/ [ K% h# \
else: 0 f; }# |8 X' K9 A5 P! r return fibonacci(n - 1) + fibonacci(n - 2)- U5 v/ f$ ?7 b# z# ?/ Z
4 T l+ C( q. s7 D3 n) _! U# Example usage, G' h! C$ }( f
print(fibonacci(6)) # Output: 8 ' m* R$ w1 h* Q( A- O+ ~6 }4 I2 H `9 l- j1 C. k4 [8 D2 Y b
Tail Recursion * L4 |1 I: q( g' e 9 e% w- Q* R& l/ [, e& wTail 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). 6 [+ K7 ?! C. x% k$ N9 G Q8 @7 \ $ K, T/ w/ I' OIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。