8 U: p1 h# ]2 ^6 @ G L; q) q7 m2. **递归条件(Recursive Case)** 8 `) P) ?: U4 h* o1 k1 D* h0 ]3 P- g& H - 将原问题分解为更小的子问题 # r8 @ {4 s# E: x K! h, i - 例如:n! = n × (n-1)!5 m2 l2 T1 {4 L
* c$ C& B, C) ~4 x% d' z0 s& i. J 经典示例:计算阶乘 5 y$ X. r* z- O5 r! z9 Fpython 3 i8 f" a0 d/ ~+ S/ \2 Ldef factorial(n): A- X# J; t1 A
if n == 0: # 基线条件1 f$ ^$ X, I( n6 `% }
return 1 # _9 _$ @3 h2 c4 W( P else: # 递归条件 $ N" c4 v- g/ q% B, d" C- \ return n * factorial(n-1)- g1 h9 _ E1 w% z
执行过程(以计算 3! 为例): ' {# L& o: \$ f8 O$ Z- p# a; Ffactorial(3) 7 t- f2 N8 m% a% B3 * factorial(2) 1 `: y3 e) Z! ~/ W* d' Z" z/ | b* Z3 * (2 * factorial(1))! Y L5 J0 ?4 Z. h9 q" ]
3 * (2 * (1 * factorial(0))) 6 i6 X% V- F( ?; e, z. x" ?" B, b6 T3 * (2 * (1 * 1)) = 6 2 b0 A- w" s _ / C/ {* `" C; G2 f7 o. I7 p% D 递归思维要点% r1 M- n) N: o! Z, N
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 - s% g, L$ W/ e4 ^3 {; w2. **栈结构**:每次调用都会创建新的栈帧(内存空间) & W$ |, x( l @& S( o5 v: \3. **递推过程**:不断向下分解问题(递)5 |& h9 Z1 l4 {/ U
4. **回溯过程**:组合子问题结果返回(归)& O; b5 K- V, Z, T
, h' J% U0 o- ~2 T' V9 I i
注意事项 ! j0 R- _; \+ u: n! O% L) N必须要有终止条件 4 G# l/ o& g( W+ n递归深度过大可能导致栈溢出(Python默认递归深度约1000层)2 c. W- E- r4 T& ?0 g
某些问题用递归更直观(如树遍历),但效率可能不如迭代) m9 Q& b6 ]& P+ x
尾递归优化可以提升效率(但Python不支持) 2 D5 Z: U- @' W' l7 |3 |& ?6 M: u4 n$ x1 i* B( z& Z
递归 vs 迭代 ' G" ?" q. s+ Q& H; H5 a3 k5 _| | 递归 | 迭代 | ; R/ _0 a) o' N$ o4 b; X8 i- D/ ^|----------|-----------------------------|------------------| p4 G: N/ c& x% R p/ a. R3 l* ]
| 实现方式 | 函数自调用 | 循环结构 | $ w; u B( A- n9 q4 ~/ m| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | : _/ M8 v0 ]' Q9 F/ j9 @| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |, W9 u) W1 H: z; A
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | 7 o0 u$ [8 j& Q) p% }4 B" e; o- `! n/ {: Z
经典递归应用场景7 x4 B) |! Q: F- [- o' G. ?# i2 z/ D
1. 文件系统遍历(目录树结构)4 m3 s- `) R( o2 @. M( i4 ~
2. 快速排序/归并排序算法 8 |4 ?% T9 P# y' f: S: N3. 汉诺塔问题$ C* L* [. S2 @" O6 U* _6 ^7 K
4. 二叉树遍历(前序/中序/后序) 3 U% l3 t: X, V: u& G0 z5. 生成所有可能的组合(回溯算法) 0 m$ j3 c. | @2 v, P4 ~' R8 b $ @' s b. N6 |; c+ x$ W试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, 8 g4 @3 X" w7 d) O. U我推理机的核心算法应该是二叉树遍历的变种。 : j b" [ i2 u! q* w另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: * S9 I, I& f+ w& E1 kKey Idea of Recursion$ d/ G' U6 V9 [. e5 K# n
* ?# }7 G6 X9 C' O/ h3 ^
A recursive function solves a problem by:: {2 T2 D6 m& I5 i0 Y1 u3 O8 T
* e7 c6 M& l+ A! N Breaking the problem into smaller instances of the same problem. 0 `& _0 o$ ?; L1 D( H0 b9 T% P" a' M7 z
Solving the smallest instance directly (base case). ; r# D7 `1 h* c. U' d ( u- C3 \, ]- L/ `2 c Combining the results of smaller instances to solve the larger problem.( t8 t4 n @, f* d0 I
2 c9 b7 U; K3 g& j% N, f& kComponents of a Recursive Function8 F. g. ~2 k* f, Q) [% j
) {6 M3 p6 q! b% H. @/ I c
Base Case:9 C, N; Q5 Z' W; [9 f4 ?
0 T" X I2 @% g7 q: v) t+ D This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 4 Z, j `# R9 Z0 K % J* y( r a0 [# v' Z. c! m9 K V It acts as the stopping condition to prevent infinite recursion.) T' C- i' f4 ^8 J; ?4 P5 S3 ?
, n7 {7 e7 C( |5 n Example: In calculating the factorial of a number, the base case is factorial(0) = 1.$ [/ F p/ G0 j0 ?' [. o! }
% r" _6 V& d: j* f1 M2 B" I3 V# m; p
Recursive Case: 5 F ` p) v* c% K9 B6 | : Y! }: T$ Q2 u; s This is where the function calls itself with a smaller or simpler version of the problem. * ^) p* d7 ?/ x! s8 T) U & q( q' N6 [6 S! E/ H1 E4 _ Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). ( v. `) `4 n) c# a. I5 u- Q, C! I, l9 X E- A5 ~9 c; b! f5 s
Example: Factorial Calculation ' k# ~' v. X4 ?+ b. l* ]# Z' l5 p- Z
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: p: r' F6 T1 X. Z% a, ~" a " ]" w( v7 A e1 N' V! i" ? Base case: 0! = 15 B) h7 J# D& q6 E
% T( [% D7 W, @ Recursive case: n! = n * (n-1)!" O, S0 n4 r3 e# x- |" U2 \
' }. I; C2 n6 y6 _+ _2 v$ J+ j
Here’s how it looks in code (Python): - k6 n* }5 ^9 y4 ~8 ^. hpython & I; L4 w: T9 E$ c( E6 A6 K# I% H0 Q% Y. o0 y2 @& [
; y5 l4 v8 S; z e) s. Y5 i9 bdef factorial(n):6 K. F" g B1 z0 ~ n
# Base case . z6 h0 E* U+ M6 z9 h/ s2 R if n == 0: 6 d, t+ {/ @0 M& `; ^9 v return 1 " H2 @6 I R8 l1 d9 ? # Recursive case* Y, b+ ]4 K p9 D+ T, R+ V
else:% Q& A5 K6 M T* h9 O) y
return n * factorial(n - 1) * }/ H- b9 p" q/ U: u" G5 X6 W; L# Q2 j1 W7 t
# Example usage ; K. i+ ^" k, [* uprint(factorial(5)) # Output: 1207 b! K+ A ]' M; |- ]$ _# s7 H
5 }" F. \- k0 g5 }1 L; M. lHow Recursion Works 5 h9 j) s ?2 P9 y1 k* Z' X; E3 s1 X' a& ^& b
The function keeps calling itself with smaller inputs until it reaches the base case.1 V" M1 `' D6 `' | J
% N. o8 I7 X- ?3 a# t Once the base case is reached, the function starts returning values back up the call stack.' @. ~% T& B7 _$ B6 q& w' K d
9 f/ M2 n5 k, c These returned values are combined to produce the final result. J7 ~5 S( l0 k" n! m2 d. J1 ^0 z0 N- ]3 [; Y
For factorial(5):9 |. \0 \% N+ l7 R
P6 z r. |8 ? * c, F1 X0 V7 P+ |* Q8 Zfactorial(5) = 5 * factorial(4)& \6 l, N" P) k1 d
factorial(4) = 4 * factorial(3)5 a' | V4 M; o* R) Q' A
factorial(3) = 3 * factorial(2) + v1 y$ R) x: m7 V! O; [( Vfactorial(2) = 2 * factorial(1) 0 R' \2 \( K& G3 t4 P, m* _factorial(1) = 1 * factorial(0) - u1 K9 t4 N5 b8 [& P. e! sfactorial(0) = 1 # Base case 6 i7 p9 h' p% i$ i+ D1 D- a% M4 H! y3 Z5 h
Then, the results are combined: }& M3 s) u/ C8 T1 H' B
4 J1 I2 Q+ f& C6 l 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). : B! k8 k5 M- f& I. A' ~ H4 }/ R6 }: ^/ c6 \" E6 M* J
Readability: Recursive code can be more readable and concise compared to iterative solutions. / s) q& {1 h% B1 P% x- Q9 n , K( E$ V, q3 ^0 I( O( ~: w# l; o4 fDisadvantages of Recursion' X! v# Y$ i! H8 G3 @1 b' Z% k: o( U
: h# w( n4 {' K0 g* c. D9 [ 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 E% |. r" T% w* S" M$ ?6 \8 [. @/ B% o+ w
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). ! w/ h" h8 [) V, \7 \4 x 7 z* R! l: i4 V) i& }+ t/ PWhen to Use Recursion + W1 y& j- K5 l7 Y" L3 S+ e( a2 g6 P0 n3 [7 |! i/ J& Y/ z- _; U
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). r) z/ x: e: g5 `9 G) n2 [ ( `+ f6 g; ]( W6 d4 c _' J Problems with a clear base case and recursive case. 3 D* T' m( D5 a1 e( \1 x1 X2 ? D8 X+ q T
Example: Fibonacci Sequence$ j) i$ _# L, h) b3 M
: C3 o: P9 E+ y: X5 x, N @6 N, X8 x4 {
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:; d8 v" x% D! @. F% Y7 P
3 x7 s2 s* }' T3 w" e' K3 R
Base case: fib(0) = 0, fib(1) = 12 }5 c B- ]. V) [# q0 o2 _
( ^7 i/ h- J+ x; c6 D0 d6 P
Recursive case: fib(n) = fib(n-1) + fib(n-2) , Y0 z! X. e$ s . d4 i8 E' |# t* d( Z4 `4 |' X# [python 8 l( D- w0 p, Y4 h! `0 f& k, Y1 l d5 o# E% b X0 t, D
, d! h0 z$ \/ C6 \, ?def fibonacci(n):- a* K7 d( d( [( d
# Base cases4 C! `8 h# S$ d$ ]" u2 F0 y
if n == 0: # r' w3 h. ^+ ?; H& M1 [' s C return 00 }+ |7 c0 J! i2 N8 k
elif n == 1:( Z% W) k1 d" L0 S7 E
return 1 L3 R) c4 f$ e1 x1 A, x
# Recursive case - @! e" A' B$ u1 C k3 H else: , F6 M! }* k6 n, |3 ~ return fibonacci(n - 1) + fibonacci(n - 2) & U% K9 c3 N1 z2 |$ p + y( u7 z0 W( ], F# Example usage ' Y" ], m0 O: d# Z7 Iprint(fibonacci(6)) # Output: 8 ; P3 ?! D* v7 Z. n & |( k5 ]6 ~4 t N+ c8 N, N$ FTail Recursion 7 `- N9 z& w5 _( P2 J5 b( ]) G + C5 e4 b2 f3 [& p( q7 w, Y, `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). 8 f( p8 j2 u, S9 E) N 2 y4 v* T# E" e0 l& x+ f; JIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。