F8 u& H: U- e/ d8 Y5 I2 V解释的不错 7 j$ N5 D7 k& M: z/ |5 d8 {* K" u! F" l* f4 m
递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 / Y7 Y1 p5 y7 W1 w% M- v+ \4 k, S; P
关键要素5 C4 P; e# n# \" ]% k, S2 X) W0 M: m
1. **基线条件(Base Case)** % q8 A* h' P/ ]! P. _( a6 u - 递归终止的条件,防止无限循环9 X4 b: _% i) [ B& j: S, r! k/ y
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 8 L7 S! T. X0 C- F/ e, v/ m ' D: D& Y1 f3 ]- v% z7 m! K) X* A2. **递归条件(Recursive Case)**5 n/ ]) H9 f. U0 k
- 将原问题分解为更小的子问题 j) j) {0 L; L3 ~- e - 例如:n! = n × (n-1)!2 H7 i' {2 o% z$ P# l5 a
7 n! _5 x9 B/ ~; M, r3 C6 n 经典示例:计算阶乘2 W: }0 U: T* r8 X$ f- R7 X
python; Q1 j I4 w) i. ^0 V. G9 b1 N) r* ]
def factorial(n):$ p; ~9 }/ D% g5 U2 V
if n == 0: # 基线条件, O5 P9 K* J& g
return 1 " E- k' H/ R0 q5 p! {1 r else: # 递归条件 * G3 g# {( T( w5 U; X Z1 e* ` return n * factorial(n-1)% t8 U& ]6 c6 D
执行过程(以计算 3! 为例):% ^$ n8 ]1 M ]( C W; d- L
factorial(3)+ e x: E7 g2 d) ^: Q) A3 I
3 * factorial(2)) U- _: j$ w" e$ s% I6 h
3 * (2 * factorial(1)) 7 _1 w- @ o# a5 h; T+ ?3 * (2 * (1 * factorial(0))), U. |8 H$ r: c5 H, p2 B7 R: I
3 * (2 * (1 * 1)) = 6 9 z) n$ X* M7 l( d- P5 } 0 n& t. S# r" Q1 k 递归思维要点 o" ]8 o. w6 M1. **信任递归**:假设子问题已经解决,专注当前层逻辑 2 `* c# {' p) h, c6 ~( X3 |2. **栈结构**:每次调用都会创建新的栈帧(内存空间) # A- V+ h( \4 f$ x* b0 L, p3. **递推过程**:不断向下分解问题(递); P n# B/ B0 |$ G j, }2 { p
4. **回溯过程**:组合子问题结果返回(归) * h, [" D' I* n- N- Y 7 \; B, F* W& K: q- I( `" [ 注意事项6 B' i1 `: J) \
必须要有终止条件" p8 `- g$ `; m/ ]- b( W0 ~
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)% d4 i8 `, c9 G" K2 [, m- R1 k
某些问题用递归更直观(如树遍历),但效率可能不如迭代 / c* T5 |% E' m尾递归优化可以提升效率(但Python不支持) K8 c' q5 ^ {& [5 R Q
4 _! f5 x3 }) F% h
递归 vs 迭代* m; _+ ^4 A2 n+ x+ q+ e9 Z# X% l
| | 递归 | 迭代 |* h% ~* I5 A; ], |2 C0 a
|----------|-----------------------------|------------------|% K) \1 L: L) C; u/ P+ P" _+ k( n
| 实现方式 | 函数自调用 | 循环结构 |, {+ _! R$ c \8 I8 V8 H
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |( f6 N0 N, T) I6 i! W3 K# t
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | ! p% F2 w# }$ P {8 x. [- p1 e| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | c" \# }8 F5 ^% p2 D; w
1 q$ B2 y3 P# B( \
经典递归应用场景 0 l6 }# W9 w( o" i$ r1 g1. 文件系统遍历(目录树结构)7 e/ U: W1 ]5 H( y {
2. 快速排序/归并排序算法6 [3 p9 P$ t, S @1 g7 [
3. 汉诺塔问题 9 W. b. f2 t7 Q6 g4. 二叉树遍历(前序/中序/后序) ! u2 x O$ h9 [ e5. 生成所有可能的组合(回溯算法) + `+ w) c* G$ k$ J6 Y; a5 k! G + J$ }& T7 g* c m试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, ' U. e! e* H. ?我推理机的核心算法应该是二叉树遍历的变种。 ' ?; ?4 b7 A' T5 I) ?, G另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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 K( [! ^. t$ E+ N/ e+ w( Y% D
Key Idea of Recursion / e7 B( K: h4 H! B) g 2 ~4 [4 c# @; h$ ~A recursive function solves a problem by: / M0 r/ Y5 t+ E/ P# [2 H ) E9 t' i; A9 X: M) k2 c9 n+ s Breaking the problem into smaller instances of the same problem.; k3 o* v% s/ E2 ~7 G
: ]! f$ `" u- }5 n Solving the smallest instance directly (base case).. I: l/ f& f/ @. A
( w9 m( `3 |" o& ^& J+ `
Combining the results of smaller instances to solve the larger problem. 4 }$ v- Z' F! ` J/ ?) U5 }9 ]3 f d5 V3 h; {
Components of a Recursive Function* I+ s- M0 d ?. G6 z
3 {: c) Y* g$ a2 y8 p. m
Base Case:) ~9 i- `# W7 d- L
; a* B8 Q0 G& t+ N" {
This is the simplest, smallest instance of the problem that can be solved directly without further recursion. ) ]" n V$ b! V% a- H& X3 k7 C) p1 o6 L4 W2 F! y6 |* J0 u3 ?2 g
It acts as the stopping condition to prevent infinite recursion. 2 f; a6 ]' x' T* ]5 C( T' d8 G% N' J, n: ~
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. J2 ~: L1 {2 }- a% R; W' @2 e( N/ g/ ], _( S( R) F3 X
Recursive Case: ( Q. k1 f+ u9 B( n4 m: ]! n 9 @( s( H6 d2 d# O4 S This is where the function calls itself with a smaller or simpler version of the problem.- y: X2 [! A* L. n; M
3 V6 {1 V5 J( `
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).: O7 o, H* X/ m* V
( Y/ E Y. L1 \* @; xExample: Factorial Calculation2 M+ O' J9 ~( N6 o2 Q
4 r% b5 o; E3 M( q9 j' m. U
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:8 Y- [% W0 ]2 V q7 W# C
2 c9 B) H; Q! q
Base case: 0! = 1/ D; P1 k4 S! b" H
! N4 V4 ~. Z5 L- v& c0 a Recursive case: n! = n * (n-1)! - G. J$ }, G- B2 m$ B1 ^1 Y2 G7 ~4 ^/ f' x3 f8 Y. Y; E0 {+ ^
Here’s how it looks in code (Python): $ q& p7 t9 z$ b6 V3 rpython* Y) u6 p& J0 e, G3 C. z- q
9 m8 T9 s; S' e2 }9 P1 \3 v3 T 1 m3 S* A/ c( O; P! D9 e& }0 adef factorial(n): A5 M$ ~$ e- \, ]% a- r! [
# Base case % O# Y/ j3 @1 F- H. @9 c* \& n if n == 0:5 e; ]/ j+ T |4 g* N- R
return 1 5 c- X6 x$ I" M$ E9 p. j( _; M # Recursive case 6 u a! K; ?2 s# f0 a) C. E else:/ Q- h7 Z' g6 E' E- E1 M5 ?0 C
return n * factorial(n - 1)( w6 |6 y6 N- D8 @7 U- E" i
3 z) Z! r. B5 q3 J# Example usage % j: Z$ m! S9 r5 s/ pprint(factorial(5)) # Output: 120 , w: f' s1 ?; h. v0 m1 ?* @- B1 H, u
How Recursion Works9 U) ^2 X4 b9 E( D
/ o* O- K4 ^7 M* {+ U. }# i' l
The function keeps calling itself with smaller inputs until it reaches the base case. ; _' o2 `) s+ L - O! M' f2 P2 P! N" @. k2 e5 M3 b Once the base case is reached, the function starts returning values back up the call stack. x/ t0 V- X t- u* h9 V3 L
3 i. J3 G% q$ t8 \1 O
These returned values are combined to produce the final result. " S# D Q6 ~+ C. K. q7 X 8 h" S6 `& D8 B9 VFor factorial(5): , v- V3 L1 `) t# i" @ 3 x3 B2 V* N; B0 }+ r 5 H- H3 W: t6 @) u2 A0 u. ^* s: ] Jfactorial(5) = 5 * factorial(4)+ z* u* U9 g0 I3 d3 D
factorial(4) = 4 * factorial(3)8 Q2 L4 E, z+ h' C' y' g
factorial(3) = 3 * factorial(2) p( f7 a9 X. L% ~4 _ j# u+ J
factorial(2) = 2 * factorial(1) ! Q" }3 b! {6 t3 X) Xfactorial(1) = 1 * factorial(0)1 T. w/ q1 l( j
factorial(0) = 1 # Base case 8 q3 Q, k. d( F7 y9 s* q6 x2 ], d' h' N, ~4 i5 j2 q V
Then, the results are combined:( J: i3 ~ x3 }8 f" c
7 z& S- ~7 u+ G6 H 2 z" E) v5 v/ I M7 r. ^4 s9 t: j! Afactorial(1) = 1 * 1 = 1& Z; ^( `% i% w( K
factorial(2) = 2 * 1 = 2 & a7 Y3 ~; u0 u" O0 v+ K* Zfactorial(3) = 3 * 2 = 6 " ^' h: q9 i2 h! gfactorial(4) = 4 * 6 = 24% h2 x7 q/ U0 `, J; o" W
factorial(5) = 5 * 24 = 120# F8 Y, C2 ]% ^8 s1 h% e
; b7 {: u2 q9 p2 F7 n( @
Advantages of Recursion$ N, f( U' w- g7 [6 T
1 n% y+ Z/ x2 i
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).* \* M2 _0 Z* n# }7 e
' m5 R1 u9 g: a, W) I Readability: Recursive code can be more readable and concise compared to iterative solutions.; P$ P7 D! C1 k$ X1 @3 p
9 _! z/ V7 ?; n2 Q. ?& c, WDisadvantages of Recursion # D$ Q7 w* L" B+ N% r' U0 I5 S8 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.# g8 E1 M, `! F- J$ S
& I' r" g1 [: e4 ?9 t% O
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). + o* p$ Q( l6 f1 k; ~9 T- T0 K# [; U0 U: Q+ P4 p6 \7 Z+ ~6 O0 o
When to Use Recursion ! R5 z4 s) a' _ m2 O5 Q: R. l( q/ ]! w T* ?. d' E& \
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). ! l% X! x! T, R$ o; F4 n& v 2 d( z4 z: A" A2 x Problems with a clear base case and recursive case. ' ~ _4 J& r% F' N* X! @4 X( }: G+ V! r
Example: Fibonacci Sequence1 G2 I8 u) ^/ ^' ^# M
# d. E, R9 i/ `5 O+ G- wThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: a3 c6 t6 B1 C7 T/ [8 B ' E5 q: |. i4 J. R! m8 X! ~ Base case: fib(0) = 0, fib(1) = 1 & A( `& t0 W7 r! |+ U/ E9 T) M& U3 l ; G3 U' }9 m9 \/ I# `) L9 g! _ Recursive case: fib(n) = fib(n-1) + fib(n-2) % ?9 @$ g( {# ^: P6 _* ^ . E8 N/ l. Q% apython " G0 E4 x. d% E 5 u- x$ d% h9 M$ f T( l6 T/ i7 n" g! u7 ydef fibonacci(n): 8 D: C* p- \! e; r& w # Base cases 4 E+ G2 F; E# z& l$ B- U7 I% W: I if n == 0: X' n4 l/ ?6 z" _ return 0( @$ K9 w( m) Q/ A0 `
elif n == 1:9 ~# k$ O2 |' Y
return 1 . V" P" f3 `. u, [- f8 }" h # Recursive case3 F E! b/ R2 x6 v& ^* j3 o
else: + E$ F# U, [6 ] return fibonacci(n - 1) + fibonacci(n - 2) h& @6 p5 {; l3 Z0 g7 X4 Y" j$ S% C6 g6 B
# Example usage / A6 Z6 Y$ {6 T2 c9 o. U6 `print(fibonacci(6)) # Output: 8 - g) G; p7 v6 \! |! a 8 ]) m6 m e6 }" _( JTail Recursion3 v: ~. [9 X7 C+ J9 H V
, u: T$ w7 |( i' t; P, C. b3 I
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). 5 x$ [9 s( F5 R# j, a: y7 B8 Q; l* k8 ]7 _8 U
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 现在的开发流程,让一个老同志复习复习,快忘光了。